#if defined(ARCTIC)

#if (FEATURE_MODE == 0)
/**
 @file sys_usw_xdata.c

 @date 2022-6-16

 @version v1.0
*/

/****************************************************************************
 *
* Header Files
*
****************************************************************************/
#include "sal.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_spool.h"
#include "ctc_warmboot.h"
#include "ctc_linklist.h"
#include "ctc_common.h"


#include "sys_usw_common.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_register.h"
#include "sys_usw_xdata.h"
#include "sys_usw_register.h"
#include "sys_usw_acl_api.h"

#include "drv_api.h"


/****************************************************************************
 *
* Defines and Macros
*
*****************************************************************************/
sys_xdata_master_t* p_xdata_master[CTC_MAX_LOCAL_CHIP_NUM_PP];

sys_xdata_local_mapping_t local_mapping[SYS_XDATA_LOCAL_FIELD_MAX] = {{CTC_XDATA_WIDTH_16, 0, 0}, {CTC_XDATA_WIDTH_16, 16, 0}, {CTC_XDATA_WIDTH_16, 32, 0},\
    {CTC_XDATA_WIDTH_16, 48, 0},{CTC_XDATA_WIDTH_8, 64, 0},{CTC_XDATA_WIDTH_8, 72, 0},{CTC_XDATA_WIDTH_8, 80, 0},{CTC_XDATA_WIDTH_8, 88, 0},{CTC_XDATA_WIDTH_8, 96, 0},\
    {CTC_XDATA_WIDTH_8, 104, 0},{CTC_XDATA_WIDTH_4, 112, 0},{CTC_XDATA_WIDTH_4, 116, 0},{CTC_XDATA_WIDTH_4, 120, 0}, {CTC_XDATA_WIDTH_4, 124, 0}};

#define XDATA_FLEX_KEY_HASH_SIZE   1024

#define SYS_XDATA_FK_SIZE_SINGLE   0
#define SYS_XDATA_FK_SIZE_DOUBLE   1
#define SYS_XDATA_FK_SIZE_QUAD     2

#define SYS_XDATA_PROF_TYPE_DSSCL_ID_MAX        3
#define SYS_XDATA_PROF_TYPE_DSMAC_ID_MAX        1
#define SYS_XDATA_PROF_TYPE_DSIP_ID_MAX         1
#define SYS_XDATA_PROF_TYPE_DSACL_ID_MAX        3
#define SYS_XDATA_PROF_TYPE_EGS_DSACL_ID_MAX    1
#define SYS_XDATA_PROF_TYPE_DSNEXTHOP_ID_MAX    3
#define SYS_XDATA_PROF_TYPE_DSTUNNEL_ID_MAX     3
#define SYS_XDATA_PROF_TYPE_DSFLOW_ID_MAX       1
#define SYS_XDATA_PROF_TYPE_DSMET_ID_MAX       7
#define SYS_XDATA_PROF_TYPE_DSMPLS_ID_MAX       0

#define _SYS_FK_MASK_80BITS       80
#define _SYS_FK_MASK_128BITS      128

#define SYS_XPI_PATH_TYPE_OFFSET 124
#define SYS_XDATA_PATH_LOGIC_PORT_EXT_POS 0

#define SYS_FIELD_KEY_INVALID 0x3FF

#define SYS_XDATA_CHECK_WIDTH(width)   (CTC_XDATA_WIDTH_4 == (width) || CTC_XDATA_WIDTH_8 == (width) || CTC_XDATA_WIDTH_16 == (width))
#define SYS_XDATA_CHECK_OFFSET(bmp, start, end)\
{\
    int32 count = 0;\
    int32 width = end - start + 1;\
    CTC_BMP_COUNT_RANGE(bmp, count, start, width);\
    if(count)\
    {\
        return CTC_E_INVALID_PARAM;\
    }\
}

enum sys_xdata_fk_prof_node_e
{
    SYS_XDATA_FK_PROF_NODE_I_SCL = 0,
    SYS_XDATA_FK_PROF_NODE_TUNNEL = SYS_XDATA_FK_PROF_NODE_I_SCL,
    SYS_XDATA_FK_PROF_NODE_MAC,
    SYS_XDATA_FK_PROF_NODE_IP = SYS_XDATA_FK_PROF_NODE_MAC,
    SYS_XDATA_FK_PROF_NODE_FLOW,
    SYS_XDATA_FK_PROF_NODE_FLOW_EXT = SYS_XDATA_FK_PROF_NODE_FLOW,
    SYS_XDATA_FK_PROF_NODE_X_HASH,
    SYS_XDATA_FK_PROF_NODE_I_IPFIX,
    SYS_XDATA_FK_PROF_NODE_E_SCL,
    SYS_XDATA_FK_PROF_NODE_E_IPFIX,
    SYS_XDATA_FK_PROF_NODE_NUM
};

const _sys_xdata_fk_info_t userid_fk_info[3][3] = {
    {/*replace1*/
        /*single*/
        {DsUserIdXKeySingleHashKey_t, DsUserIdXKeySingleHashKey_u_g2_data_f, 0},
        /*double*/
        {DsUserIdXKeyDoubleHashKey_t, DsUserIdXKeyDoubleHashKey_u_g2_data_f, 0},
        /*quad*/
        {DsUserIdXKeyQuadHashKey_t, DsUserIdXKeyQuadHashKey_u_g2_data_f, 0}
    },
    {/*append*/
        /*single*/
        {DsUserIdXKeyDoubleHashKey_t, DsUserIdXKeyDoubleHashKey_u_g1_data_f, 1},
        /*double*/
        {DsUserIdXKeyQuadHashKey_t, DsUserIdXKeyQuadHashKey_u_g1_data_f, 1},
        /*quad*/
        {0,0,0}
    },
    {/*replace2*/
        /*single*/
        {DsUserIdXKeySingleHashKey_t, DsUserIdXKeySingleHashKey_u_g2_data_f, 2},
        /*double*/
        {DsUserIdXKeyDoubleHashKey_t, DsUserIdXKeyDoubleHashKey_u_g2_data_f, 2},
        /*quad*/
        {DsUserIdXKeyQuadHashKey_t, DsUserIdXKeyQuadHashKey_u_g2_data_f, 2}
    }
};
const _sys_xdata_fk_info_t i_scl_fk_info[3][3] = {
    {/*replace1*/
        /*single*/
        {TempSclTcamXKeySingle_t, TempSclTcamXKeySingle_data_f, 0},
        /*double*/
        {TempSclTcamXKeyDouble_t, TempSclTcamXKeyDouble_data1_f, 0},
        /*quad*/
        {TempSclTcamXKeyQuad_t, TempSclTcamXKeyQuad_data2_f, 0}
    },
    {/*append*/
        /*single*/
        {TempSclTcamXKeyDouble_t, TempSclTcamXKeyDouble_data1_f, 1},
        /*double*/
        {TempSclTcamXKeyQuad_t, TempSclTcamXKeyQuad_data2_f, 1},
        /*quad*/
        {0,0,0}
    },
    {/*replace2*/
        /*single*/
        {TempSclTcamXKeySingle_t, TempSclTcamXKeySingle_data_f, 2},
        /*double*/
        {TempSclTcamXKeyDouble_t, TempSclTcamXKeyDouble_data1_f, 2},
        /*quad*/
        {TempSclTcamXKeyQuad_t, TempSclTcamXKeyQuad_data2_f, 2}
    }
};
const _sys_xdata_fk_info_t flow_ext_fk_info[3][1] = {
    {/*replace1*/
        /*single*/
        {DsXLookup0HashKey_t, DsXLookup0HashKey_keyData_f, 1}
    },
    {/*append*/
        /*single*/
        {DsXLookup1HashKey_t, DsXLookup1HashKey_keyData_f, 1}
    },
    {/*replace2*/
        /*single*/
        {DsXLookup0HashKey_t, DsXLookup0HashKey_keyData_f, 1}
    }
};
const _sys_xdata_fk_info_t flow_fk_info[3][3] = {
    {/*replace1*/
        /*double*/
        {DsFlowXKeyDoubleHashKey_t, DsFlowXKeyDoubleHashKey_u_g2_data_f, 0},
        {DsFlowXKeyDoubleHashKey_t, DsFlowXKeyDoubleHashKey_u_g2_data_f, 0},
        /*quad*/
        {DsFlowXKeyQuadHashKey_t, DsFlowXKeyQuadHashKey_u_g2_data_f, 0}
    },
    {/*append*/
        /*double*/
        {0,0,0},
        {DsFlowXKeyQuadHashKey_t, DsFlowXKeyQuadHashKey_u_g1_data_f, 1},
        /*quad*/
        {0,0,0}
    },
    {/*replace2*/
        /*double*/
        {0,0,0},
        {DsFlowXKeyDoubleHashKey_t, DsFlowXKeyDoubleHashKey_u_g2_data_f, 2},
        /*quad*/
        {DsFlowXKeyQuadHashKey_t, DsFlowXKeyQuadHashKey_u_g2_data_f, 2}
    }
};
const _sys_xdata_fk_info_t e_scl_fk_info[3][1] = {
    {/*replace1*/
        /*double*/
        {EgrSclHashKey_t, EgrSclHashKey_u1_gXKey_data_f, 0}
    },
    {/*append*/
        /*double*/
        {0,0,0}
    },
    {/*replace2*/
        /*double*/
        {EgrSclHashKey_t, EgrSclHashKey_u1_gXKey_data_f, 2}
    }
};
const _sys_xdata_fk_info_t ipfix_fk_info[3][3] = {
    {/*replace1*/
        /*single*/
        {DsIpfixXKeySingleHashKey_t, DsIpfixXKeySingleHashKey_u_g2_data_f, 0},
        /*double*/
        {DsIpfixXKeyDoubleHashKey_t, DsIpfixXKeyDoubleHashKey_u_g2_data_f, 0},
        /*quad*/
        {DsIpfixXKeyQuadHashKey_t, DsIpfixXKeyQuadHashKey_u_g2_data_f, 0}
    },
    {/*append*/
        /*single*/
        {DsIpfixXKeyDoubleHashKey_t, DsIpfixXKeyDoubleHashKey_u_g1_data_f, 1},
        /*double*/
        {DsIpfixXKeyQuadHashKey_t, DsIpfixXKeyQuadHashKey_u_g1_data_f, 1},
        /*quad*/
        {0,0,0}
    },
    {/*replace2*/
        /*single*/
        {DsIpfixXKeySingleHashKey_t, DsIpfixXKeySingleHashKey_u_g2_data_f, 2},
        /*double*/
        {DsIpfixXKeyDoubleHashKey_t, DsIpfixXKeyDoubleHashKey_u_g2_data_f, 2},
        /*quad*/
        {DsIpfixXKeyQuadHashKey_t, DsIpfixXKeyQuadHashKey_u_g2_data_f, 2}
    }
};

typedef struct
{
    uint8 width;
    uint8 src_offset;
    uint8 udf_en;
    uint8 field_num;
    char* field[5];
    char* udf;
}sys_xdata_solid_map_t;

sys_xdata_solid_map_t local_solid_map[CTC_XDATA_LOCAL_TYPE_MAX][SYS_XDATA_LOCAL_FIELD_MAX] = 
{
/*CTC_XDATA_LOCAL_TYPE_SCL*/
{{16,0,0,1,{"tunnelAuxData(23,8)"}},{16,16,0,1,{"PRE.g2.data(31,16)"}},{16,32,0,1,{"PRE.g2.data(15,0)"}},{16,48,0,3,{"PI.vlanRangeType(0,0)","PI.userIdVlanRangeValid(0,0)","PI.userIdVlanRangeMax(11,0)"}},
{8,64,0,1,{"PRE.g3.data(31,24)"}},{8,72,0,1,{"PRE.g3.data(23,16)"}},{8,80,0,1,{"PRE.g3.data(23,16)"}},{8,88,0,1,{"PRE.g3.data(15,0)"}},{8,96,0,1,{"tunnelAuxData(7,0)"}},{8,104,0,3,{"PR.layer3Type(3,0)","PR.vlanNum(1,0)","PR.fragInfo(1,0)"}},
{4,112,0,1,{"PR.extType(3,0)"}},{4,116,0,1,{"PR.layer4UserType(3,0)"}},{4,120,0,1,{"PR.layer4Type(3,0)"}},{4,124,0,2,{"PR.ParserResult.ipHeaderError(0,0)","PR.layer2Type(2,0)"}}  },

/*CTC_XDATA_LOCAL_TYPE_EGS_SCL*/
{{16,0,0,1,{"PI.CategoryId(15,0)"}},{16,16,0,1,{"-"}},{16,32,0,1,{"logicDestPortGid(15,0)"}},{16,48,0,1,{"PRE.g2_data(31,16)"}},
{8,64,0,1,{"PI.CategoryId(15,8)"}},{8,72,0,1,{"mplsEvpnDestEsId(7,0)"}},{8,80,0,1,{"logicDestPortGid(15,8)"}},{8,88,0,1,{"PRE.g3_data(31,24)"}},{8,96,0,1,{"PRE.g3_data(23,16)"}},{8,104,0,1,{"PRE.g3_data(15,8)"}},
{4,112,0,1,{"PI.CategoryId(15,12)"}},{4,116,0,1,{"PI.pktForwardingType(3,0)"}},{4,120,0,1,{"logicDestPortGid(15,12)"}},{4,124,0,1,{"PR.extType(3,0)"}}  },

/*CTC_XDATA_LOCAL_TYPE_FLOW_HASH*/
{{16,0,0,2,{"zero(2,0)","PI.interfaceId(12,0)"}},{16,16,0,1,{"PI.logicSrcPort(15,0)"}},{16,32,0,2,{"zero(0,0)","PI.vsiId(14,0)"}},{16,48,0,2,{"zero(1,0)","PI.vrfId(13,0)"}},
{8,64,0,3,{"PI.stpState(1,0)","PI.isDecap(0,0)","PI.tunnelType(4,0)"}},{8,72,0,3,{"PI.ipHeaderError(0,0)","PI.discard(0,0)","PI.discardType(5,0)"}},
{8,80,0,5,{"zero(0,0)","PI.layer2Type(2,0)","PI.stpState(1,0)","PI.cvlanIdValid(0,0)","PI.svlanIdValid(0,0)"}},{8,88,0,1,{"PI.svlanId(7,0)"}},{8,96,0,1,{"PI.cvlanId(7,0)"}},{8,104,0,2,{"PI.cvlanId(11,8)","PI.svlanId(11,8)"}},
{4,112,0,1,{"PI.layer3Type(3,0)"}},{4,116,0,1,{"PI.layer4Type(3,0)"}},{4,120,0,1,{"PI.layer4UserType(3,0)"}},{4,124,0,1,{"PI.vlanNum(1,0)","PI.fragInfo(1,0)"}}  },


/*CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT*/
{{16,0,0,1,{"UDF(15,0)"}},{16,16,0,1,{"UDF(31,16)"}},{16,32,0,1,{"UDF(47,32)"}},{16,48,0,1,{"UDF(63,48)"}},
{8,64,0,1,{"UDF(79,72)"}},{8,72,0,1,{"UDF(71,64)"}},{8,80,0,1,{"UDF(95,88)"}},{8,88,0,1,{"UDF(87,80)"}},{8,96,0,1,{"UDF(112,104)"}},{8,104,0,1,{"UDF(119,112)"}},
{4,112,0,1,{"udfValid(3,0)"}},{4,116,0,1,{"udfHitIndex(3,0)"}},{4,120,0,1,{"udfValid(7,4)"}},{4,124,0,1,{"udfHitIndex(7,4)"}}  },


/*CTC_XDATA_LOCAL_TYPE_IPFIX*/
{{16,0,0,2,{"zero(1,0)","PI.vrfId(13,0)"}},{16,16,0,1,{"mergeData(15,0)"}},{16,32,0,1,{"mergeData(31,16)"}},{16,48,0,1,{"-"}},
{8,64,0,2,{"PI.discard(0,0)","PI.discardType(5,0)"}},{8,72,0,1,{"PI.ttl(7,0)"}},{8,80,0,1,{"-"}},{8,88,0,1,{"-"}},{8,96,0,1,{"-"}},{8,104,0,1,{"-"}},
{4,112,0,3,{"zero(0,0)","PI.isMergeMode(0,0)","PI.mergeDataType(1,0)"}},{4,116,0,1,{"-"}},{4,120,0,1,{"-"}},{4,124,0,1,{"-"}}  },


/*CTC_XDATA_LOCAL_TYPE_EGS_IPFIX*/
{{16,0,0,1,{"PI.vrfId(13,0)"}},{16,16,0,1,{"PI.mergeData(15,0)"}},{16,32,0,1,{"PI.mergeData(31,16)"}},{16,48,0,1,{"PI.sourcePort(15,0)"}},
{8,64,0,3,{"zero(0,0)","PI.discard(0,0)","PI.discardType(5,0)"}},{8,72,0,1,{"PI.ttl(7,0)"}},{8,80,0,1,{"-"}},{8,88,0,1,{"-"}},{8,96,0,1,{"-"}},{8,104,0,1,{"-"}},
{4,112,0,3,{"zero(1,0)","PI.latencyCongestionValid","PI.microburstValid"}},{4,116,0,3,{"zero(0,0)","PI.isMergeMode(0,0)","PI.mergeDataType(1,0)"}},{4,120,0,1,{"-"}},{4,124,0,1,{"-"}}  }

};

sys_xdata_solid_map_t solid_map[CTC_XDATA_PROF_TYPE_MAX][SYS_XDATA_LOCAL_FIELD_MAX] = 
{
/*CTC_XDATA_PROF_TYPE_POST_SCL*/
{{16,0,0,1,{"PI.staticSrcCategoryId(15,0)"}},{16,16,0,1,{"PI.staticDestCategoryId(15,0)"}},{16,32,0,4,{"zero(1,0)","PI.vlanRangeType(0.0)","PI.userIdVlanRangeValid(0,0)","PI.userIdVlanRangeMax(11,0)"}},
{16,48,0,4,{"zero(1,0)","PI.vlanRangeType1(0.0)","PI.userIdVlanRangeValid1(0,0)","PI.userIdVlanRangeMax1(11,0)"}},
{8,64,0,1,{"PI.staticSrcCategoryId(15,8)"}},{8,72,0,1,{"PI.staticDestCategoryId(15,8)"}},{8,80,0,1,{"-"}},{8,88,0,1,{"-"}},{8,96,0,1,{"-"}},{8,104,0,1,{"-"}},
{4,112,0,1,{"PI.staticSrcCategoryId(15,12)"}},{4,116,0,1,{"PI.staticDestCategoryId(15,12)"}},{4,120,0,1,{""}},{4,124,0,1,{""}}  },

/*CTC_XDATA_PROF_TYPE_POST_L3IF*/
{{16,0,0,1,{"PI.portCategoryId(15,0)"}},{16,16,0,1,{"PI.vlanCategoryId(15,0)"}},{16,32,0,1,{"PI.l3IfCategoryId(15,0)"}},{16,48,0,1,{"-"}},
{8,64,0,1,{"PI.portCategoryId(15,8)"}},{8,72,0,1,{"PI.vlanCategoryId(15,8)"}},{8,80,0,1,{"PI.l3IfCategoryId(15,8)"}},{8,88,0,1,{"-"}},{8,96,0,1,{"-"}},{8,104,0,1,{"-"}},
{4,112,0,1,{"PI.portCategoryId(15,12)"}},{4,116,0,1,{"PI.vlanCategoryId(15,12)"}},{4,120,0,1,{"PI.l3IfCategoryId(15,12)"}},{4,124,0,1,{"-"}}  },

/*CTC_XDATA_PROF_TYPE_POST_TUNNEL*/
{{16,0,0,1,{"PI.tunnelIfCategoryId(15,0)"}},{16,16,0,1,{"-"}},{16,32,0,1,{"-"}},{16,48,0,1,{"-"}},
{8,64,0,1,{"PI.tunnelIfCategoryId(15,8)"}},{8,72,0,1,{"-"}},{8,80,0,1,{"-"}},{8,88,0,1,{"-"}},{8,96,0,1,{"-"}},{8,104,0,1,{"-"}},
{4,112,0,1,{"PI.tunnelIfCategoryId(15,12)"}},{4,116,0,3,{"-"}},{4,120,0,1,{"-"}},{4,124,0,1,{"-"}}  },

/*CTC_XDATA_PROF_TYPE_POST_FWD*/
{{16,0,0,1,{"PI.vsiCategoryId(15,0)"}},{16,16,0,1,{"PI.dynamicSrcCategoryId(15,0)"}},{16,32,0,1,{"PI.dynamicDestCategoryId(15,0)"}},{16,48,0,1,{"PI.dsFlowIdCategoryId(15,0)"}},
{8,64,0,1,{"PI.vsiCategoryId(15,8)"}},{8,72,0,1,{"PI.dynamicSrcCategoryId(15,8)"}},{8,80,0,1,{"PI.dynamicDestCategoryId(15,8)"}},{8,88,0,1,{"PI.dsFlowIdCategoryId(15,8)"}},{8,96,0,1,{"-"}},{8,104,0,1,{"-"}},
{4,112,0,1,{"PI.vsiCategoryId(15,12)"}},{4,116,0,1,{"PI.dynamicSrcCategoryId(15,12)"}},{4,120,0,1,{"PI.dynamicDestCategoryId(15,12)"}},{4,124,0,1,{"PI.dsFlowIdCategoryId(15,12)"}}  },

/*CTC_XDATA_PROF_TYPE_POST_ACL*/
{{16,0,0,1,{"PI.i2eSrcCid(15,0)"}},{16,16,0,2,{"zero(1,0)","PI.vrfId(13,0)"}},{16,32,0,1,{"-"}},{16,48,0,1,{"-"}},
{8,64,0,1,{"PI.i2eSrcCid(15,8)"}},{8,72,0,1,{"-"}},{8,80,0,1,{"-"}},{8,88,0,1,{"-"}},{8,96,0,1,{"-"}},{8,104,0,1,{"-"}},
{4,112,0,1,{"PI.i2eSrcCid(15,12)"}},{4,116,0,1,{"-"}},{4,120,0,1,{"-"}},{4,124,0,2,{"zero(2,0)","PI.routedPacket(0,0)"}}  },

/*CTC_XDATA_PROF_TYPE_DSSCL*/
{{16,0,0,1,{"DsUserId.u3_g1_policerPtr(15,0)"}},{16,16,0,1,{"-"}},
{8,32,0,1,{"DsUserId.u2_g2_categoryId(7,0)"}},{8,40,0,1,{"DsUserId.u2_g2_categoryId(15,8)"}},
{4,48,0,1,{"DsUserId.u1_g1_metadata(3,0)"}},{4,52,0,1,{"DsUserId.u1_g1_metadata(7,4)"}},{4,56,0,1,{"DsUserId.u1_g1_metadata(11,8)"}},{4,60,0,2,{"zero(0,0)","DsUserId.u1_g1_metadata(14,12)"}},{4,64,0,1,{"DsUserId.auxData(3,0)"}}},
/*CTC_XDATA_PROF_TYPE_DSTUNNEL*/
{{16,0,0,1,{"DsTunnelId.u1_g4_xAdData(47,32)"}},{16,16,0,1,{"DsTunnelId.u1_g4_xAdData(63,48)"}},
{8,32,0,1,{"DsTunnelId.u1_g4_xAdData(23,16)"}},{8,40,0,1,{"DsTunnelId.u1_g4_xAdData(31,24)"}},
{4,48,0,1,{"DsTunnelId.u1_g4_xAdData(3,0)"}},{4,52,0,1,{"DsTunnelId.u1_g4_xAdData(7,4)"}},
{4,56,0,1,{"DsTunnelId.u1_g4_xAdData(11,8)"}},{4,60,0,1,{"DsTunnelId.u1_g4_xAdData(15,12)"}},{4,64,0,1,{"DsTunnelId.auxData(3,0)"}}},

/*CTC_XDATA_PROF_TYPE_DSMPLS*/
{{4,0,0,2,{"zero(0,0)","DsMpls.auxData(2,0)"}},{16,16,0,0,{"-"}},
{8,32,0,0,{"-"}},{8,40,0,0,{"-"}},
{4,48,0,0,{"-"}},{4,52,0,0,{"-"}},{4,56,0,0,{"-"}},{4,60,0,0,{"-"}},{4,64,0,0,{"-"}}},

/*CTC_XDATA_PROF_TYPE_DSMACDA*/
{{16,0,0,1,{"DsMac.u1_g1_dsFwdPtr(15,0)"}},{16,16,0,1,{"-"}},
{8,32,0,1,{"DsMac.u1_g1_statsPtr(7,0)"}},{8,40,0,1,{"DsMac.u1_g1_statsPtr(15,8)"}},
{4,48,0,1,{"DsMac.u3_g2_policerPtr(3,0)"}},{4,52,0,1,{"DsMac.u3_g2_policerPtr(7,4)"}},{4,56,0,1,{"DsMac.u3_g2_policerPtr(11,8)"}},{4,60,0,1,{"DsMac.u3_g2_policerPtr(15,12)"}},{4,64,0,1,{"DsMac.auxData(3,0)"}}},

/*CTC_XDATA_PROF_TYPE_DSIPDA*/
{{16,0,0,1,{"-"}},{16,16,0,1,{"-"}},
{8,32,0,1,{"DsIp.u2_g1_rpfIfId(7,0)"}},{8,40,0,1,{"DsIp.u2_g1_rpfIfId(15,8)"}},
{4,48,0,1,{"DsIp.u3_g1_serviceId(3,0)"}},{4,52,0,1,{"DsIp.u3_g1_serviceId(7,4)"}},{4,56,0,2,{"DsIp.u3_g1_xAdData(5,4)","DsIp.u3_g1_serviceId(9,8)"}},{4,60,0,1,{"DsIp.u3_g1_xAdData(3,0)"}},{4,64,0,1,{"DsIp.auxData(3,0)"}}},

/*CTC_XDATA_PROF_TYPE_DSFLOW*/
{{16,0,0,1,{"DsFlow.u1_g1_dsFwdPtr(15,0)"}},{16,16,0,1,{"DsFlow.categoryIdOrServiceId(15,0)"}},
{8,32,0,1,{"DsFlow.u1_g1_ecmpGroupId(7,0)"}},{8,40,0,1,{"DsFlow.metadata(7,0)"}},
{4,48,0,1,{"DsFlow.u1_g1_xAdData(3,0)"}},{4,52,0,1,{"DsFlow.u1_g1_xAdData(7,4)"}},{4,56,0,1,{"DsFlow.u1_g1_ecmpGroupId(11,8)"}},{4,60,0,1,{"DsFlow.metadata(11,8)"}},{4,64,0,2,{"DsFlow.auxDataExt(0,0)","bDsFlow.auxData(2,0)"}}},

/*CTC_XDATA_PROF_TYPE_DSACL*/
{{16,0,1,2,{"DsIpeAcl.u2_gServiceId_serviceId(7,0)","DsIpeAcl.u2_gServiceId_xAdData(7,0)"},"UDF(47,32)"},{16,16,1,1,{"-"},"UDF(63,48)"},
{8,32,1,1,{"DsIpeAcl.u3_gCvlanAction_cvlanId(7,0)"},"UDF(23,16)"},{8,40,1,3,{"DsIpeAcl.u3_gCvlanAction_ccfi(0,0)","DsIpeAcl.u3_gCvlanAction_ccos(2,0)","DsIpeAcl.u3_gCvlanAction_cvlanId(11,8)"},"UDF(31,24)"},
{4,48,1,1,{"DsIpeAcl.u4_gStripOp_xAdData(3,0)"},"UDF(3,0)"},{4,52,1,1,{"DsIpeAcl.u4_gStripOp_xAdData(7,4)"},"UDF(7,4)"},
{4,56,1,2,{"DsIpeAcl.u4_gStripOp_tunnelPayloadOffset(2,0)","DsIpeAcl.u4_gStripOp_xAdData(8,8)"},"UDF(11,8)"},{4,60,1,1,{"DsIpeAcl.u4_gStripOp_tunnelPayloadOffset(6,3)"},"UDF(15,12)"},{4,64,0,1,{"DsIpeAcl.auxData(3,0)"}}},

/*CTC_XDATA_PROF_TYPE_EGS_DSSCL*/
{{16,0,0,1,{"-"}},{16,16,0,1,{"-"}},
{8,32,0,1,{"DsVlanXlate.u0_gPolicer_policerPtr(7,0)"}},{8,40,0,3,{"DsVlanXlate.u0_gPolicer_policerLvlSel(0,0)","DsVlanXlate.u0_gPolicer_policerPhbEn(0,0)","DsVlanXlate.u0_gPolicer_policerPtr(12,8)"}},
{4,48,0,2,{"DsVlanXlate.userCCos(2,0)","DsVlanXlate.userCCfi(0,0)"}},{4,52,0,1,{"DsVlanXlate.userCVlanId(3,0)"}},{4,56,0,1,{"DsVlanXlate.userCVlanId(7,4)"}},{4,60,0,1,{"DsVlanXlate.userCVlanId(11,8)"}},{4,64,0,1,{"-"}}},

/*CTC_XDATA_PROF_TYPE_EGS_DSACL*/
{{16,0,0,1,{"DsEpeAcl.u2.g1.xAdData(23,8)"}},{16,16,0,1,{"-"}},
{8,32,0,1,{"DsEpeAcl.u1.gOam.xAdData(15,8)"}},{8,40,0,1,{"DsEpeAcl.u2.g1.xAdData(7,0)"}},
{4,48,0,1,{"DsEpeAcl.u1_gOam_packetOffset(3,0)"}},{4,52,0,1,{"DsEpeAcl.u1_gOam_packetOffset(7,4)"}},{4,56,0,1,{"DsEpeAcl.u1_gOam_xAdData(3,0)"}},{4,60,0,1,{"DsEpeAcl.u1_gOam_xAdData(7,4)"}},{4,64,0,1,{"DsEpeAcl.auxData(3,0)"}}}

};

/****************************************************************************
*
* Function
*
*****************************************************************************/

STATIC int32
_sys_usw_xdata_prof_param_check(uint8 lchip, ctc_xdata_prof_t *p_prof)
{
    uint8 loop = 0;
    uint8 is_post = 0;
    uint8 src_offset_max = 0;
    uint32 xdata_bmp[2][4] = {{0}};       /* src/dst xdata */
    int32 v_bit[2] = {0};            /* src/dst valid bits */
    ctc_xdata_map_t* p_map = NULL;

    /* 1. not support update xdata prof */
    CTC_MAX_VALUE_CHECK(p_prof->type, CTC_XDATA_PROF_TYPE_MAX);
    CTC_MAX_VALUE_CHECK(p_prof->num, SYS_XDATA_PROF_FIELD_MAX-1);
    if(!p_prof->num)
    {
        return CTC_E_NONE;
    }
    is_post = (p_prof->type < CTC_XDATA_PROF_TYPE_POST_MAX) ? 1 : 0;
    src_offset_max = is_post ? 128 : 68;
    if (CTC_IS_BIT_SET(p_xdata_master[lchip]->prof_bmp[p_prof->type], p_prof->prof_id))
    {
        return CTC_E_IN_USE;
    }

    /* 2. check common width offset */
    do
    {
        p_map = &p_prof->map[loop];
        if (!p_map || (p_map->dst_offset + p_map->width) > 128 || (p_map->src_offset + p_map->width) > src_offset_max )
        {
            return CTC_E_INVALID_PARAM;
        }

        switch (p_map->width)
        {
        case CTC_XDATA_WIDTH_16:
            if(SYS_XDATA_PROF_TYPE_DSMET == p_prof->type)
            {
                continue;
            }
            if (p_map->src_offset >= 64)
            {
                return CTC_E_INVALID_PARAM;
            }
            break;
        case CTC_XDATA_WIDTH_8:
            if(SYS_XDATA_PROF_TYPE_DSMET == p_prof->type)
            {
                continue;
            }
            if ((!is_post && (p_map->src_offset < 32 || p_map->src_offset >= 64)) ||
                (is_post && (p_map->src_offset < 64 || p_map->src_offset >= 112)))
            {
                return CTC_E_INVALID_PARAM;
            }
            break;
        case CTC_XDATA_WIDTH_4:
            if(SYS_XDATA_PROF_TYPE_DSMET == p_prof->type || p_prof->type == CTC_XDATA_PROF_TYPE_DSMPLS)
            {
                continue;
            }
            if ((!is_post && p_map->src_offset < 48) ||
                (is_post && p_map->src_offset < 112))
            {
                return CTC_E_INVALID_PARAM;
            }
            break;
        default:
            return CTC_E_INVALID_PARAM;
        }
        if (0 != (p_map->src_offset % p_map->width) || 0 != (p_map->dst_offset % p_map->width))
        {
            return CTC_E_INVALID_PARAM;
        }

        /* check repeat width and offset */
        CTC_BMP_COUNT_RANGE(xdata_bmp[0], v_bit[0], p_map->src_offset, p_map->width);
        CTC_BMP_COUNT_RANGE(xdata_bmp[1], v_bit[1], p_map->dst_offset, p_map->width);
        if(v_bit[0]||v_bit[1])
        {
            return CTC_E_PARAM_CONFLICT;
        }
        CTC_BMP_SET_RANGE(xdata_bmp[0], p_map->src_offset, p_map->width);
        CTC_BMP_SET_RANGE(xdata_bmp[1], p_map->dst_offset, p_map->width);

    } while (++loop < p_prof->num);

    /* 3. per type check width offset */
    switch(p_prof->type)
    {
    case CTC_XDATA_PROF_TYPE_DSSCL:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, SYS_XDATA_PROF_TYPE_DSSCL_ID_MAX);
        /* not support only udf field gWord[1]*/
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 16, 31);
        break;
    case CTC_XDATA_PROF_TYPE_DSTUNNEL:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, SYS_XDATA_PROF_TYPE_DSTUNNEL_ID_MAX);
        break;
    case CTC_XDATA_PROF_TYPE_DSMPLS:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, SYS_XDATA_PROF_TYPE_DSMPLS_ID_MAX);
        if((1 != p_prof->num || p_prof->map[0].width != CTC_XDATA_WIDTH_4 || p_prof->map[0].src_offset != 0))
        {
            return CTC_E_INVALID_PARAM;
        }
        break;
    case CTC_XDATA_PROF_TYPE_DSFLOW:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, SYS_XDATA_PROF_TYPE_DSFLOW_ID_MAX);
        break;
    case CTC_XDATA_PROF_TYPE_DSMACDA:
#if 0
    case CTC_XDATA_PROF_TYPE_DSMACSA:
#endif
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, SYS_XDATA_PROF_TYPE_DSMAC_ID_MAX);
        /* default */
        if(p_prof->prof_id == 1)
        {/* not support field gWord[0] gWord[1] gByte[0] gByte[1] gNibble[3] */
            SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 0, 47);
            SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 60, 63);
        }
        if(p_prof->prof_id == 0)
        {/* not support only gWord[0] gWord[1]*/
            SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 0, 31);
        }
        break;
    case CTC_XDATA_PROF_TYPE_DSIPDA:
#if 0
    case CTC_XDATA_PROF_TYPE_DSIPSA:
#endif
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, SYS_XDATA_PROF_TYPE_DSIP_ID_MAX);
        /* not support only gWord[0] gWord[1]*/
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 0, 31);
        break;
    case CTC_XDATA_PROF_TYPE_DSACL:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, SYS_XDATA_PROF_TYPE_DSACL_ID_MAX);
        break;
#if 0
    case CTC_XDATA_PROF_TYPE_DSNEXTHOP:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, SYS_XDATA_PROF_TYPE_DSNEXTHOP_ID_MAX);
        /* not support only gWord[1]*/
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 16, 31);
        break;
#endif
    case CTC_XDATA_PROF_TYPE_EGS_DSSCL:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, SYS_XDATA_PROF_TYPE_DSSCL_ID_MAX);
        /* not support only udf field gWord[0] gWord[1]*/
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 0, 31);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 64, 67);
        break;
    case CTC_XDATA_PROF_TYPE_EGS_DSACL:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, SYS_XDATA_PROF_TYPE_EGS_DSACL_ID_MAX);
        /* not support only gWord[1]*/
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 16, 31);
        break;
    case SYS_XDATA_PROF_TYPE_DSMET:
        CTC_VALUE_RANGE_CHECK(p_prof->prof_id, 1, SYS_XDATA_PROF_TYPE_DSMET_ID_MAX);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 64, 127);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[1], 0, 31);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[1], 64, 127);
        break;
    case CTC_XDATA_PROF_TYPE_POST_SCL:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, 0);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 120, 127);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 80, 111);
        break;
    case CTC_XDATA_PROF_TYPE_POST_L3IF:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, 0);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 124, 127);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 88, 111);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 48, 63);
        break;
    case CTC_XDATA_PROF_TYPE_POST_TUNNEL:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, 0);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 116, 127);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 72, 111);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 16, 63);
        break;

    case CTC_XDATA_PROF_TYPE_POST_FWD:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, 0);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 96, 111);
        break;

    case CTC_XDATA_PROF_TYPE_POST_ACL:
        CTC_MAX_VALUE_CHECK(p_prof->prof_id, 0);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 116, 123);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 72, 111);
        SYS_XDATA_CHECK_OFFSET(xdata_bmp[0], 32, 63);
        break;

    default:
        return CTC_E_NOT_SUPPORT;
    }


    return CTC_E_NONE;
}
STATIC int32
_sys_usw_xdata_prof_dsmet_map(uint8 lchip,ctc_xdata_prof_t *p_prof, sys_xdata_prof_field_t* p_field, void *p_profile, uint8* dsmet_bmp)
{
    uint8 loop = 0, loop2 = 0;
    uint8 src_id = 0, dst_id = 0;
    uint8 step = 0;
    sys_xdata_prof_field_t* p_prof_field = NULL;

    step = XHeader2XHeaderHalfProfile_gDestNibbleEn_1_nibbleEn_f - XHeader2XHeaderHalfProfile_gDestNibbleEn_0_nibbleEn_f;
    sal_memset(p_field, 0, SYS_XDATA_PROF_FIELD_MAX*sizeof(sys_xdata_prof_field_t));
    do
    {
        p_prof_field = &p_field[loop];
        p_prof_field->width= p_prof->map[loop].width;
        p_prof_field->src_offset= p_prof->map[loop].src_offset;
        p_prof_field->dst_offset= p_prof->map[loop].dst_offset;
        //p_prof_field->flag= p_prof->map[loop].flag;

        switch (p_prof->map[loop].width)
        {
        case CTC_XDATA_WIDTH_16:

            loop2 = 0;
            do
            {
                src_id = p_prof->map[loop].src_offset/CTC_XDATA_WIDTH_4 + loop2;
                dst_id = (p_prof->map[loop].dst_offset - 32) / CTC_XDATA_WIDTH_4 + loop2;
                SetXHeader2XHeaderHalfProfile(V, gDestNibbleEn_0_nibbleEn_f + step * dst_id, p_profile, 1);
                SetXHeader2XHeaderHalfProfile(V, gDestNibble_0_srcNibble_f + step * dst_id, p_profile, src_id);
                CTC_BIT_SET(*dsmet_bmp, dst_id);
            } while (++loop2 < 4);
            break;
        case CTC_XDATA_WIDTH_8:

            loop2 = 0;
            do
            {
                src_id = p_prof->map[loop].src_offset/CTC_XDATA_WIDTH_4 + loop2;
                dst_id = (p_prof->map[loop].dst_offset - 32) / CTC_XDATA_WIDTH_4 + loop2;
                SetXHeader2XHeaderHalfProfile(V, gDestNibbleEn_0_nibbleEn_f + step * dst_id, p_profile, 1);
                SetXHeader2XHeaderHalfProfile(V, gDestNibble_0_srcNibble_f + step * dst_id, p_profile, src_id);
                CTC_BIT_SET(*dsmet_bmp, dst_id);
            } while (++loop2 < 2);

            break;
        case CTC_XDATA_WIDTH_4:

            loop2 = 0;
            do
            {
                src_id = p_prof->map[loop].src_offset/CTC_XDATA_WIDTH_4 + loop2;
                dst_id = (p_prof->map[loop].dst_offset - 32) / CTC_XDATA_WIDTH_4 + loop2;
                SetXHeader2XHeaderHalfProfile(V, gDestNibbleEn_0_nibbleEn_f + step * dst_id, p_profile, 1);
                SetXHeader2XHeaderHalfProfile(V, gDestNibble_0_srcNibble_f + step * dst_id, p_profile, src_id);
                CTC_BIT_SET(*dsmet_bmp, dst_id);
            } while (++loop2 < 1);

            break;
        default:
            break;
        }
    } while (++loop < p_prof->num);

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_xdata_prof_ad_map(uint8 lchip,ctc_xdata_prof_t *p_prof, sys_xdata_prof_field_t* p_field, void *p_profile)
{
    uint8 loop = 0, loop2 = 0;
    uint8 src_id = 0, dst_id = 0;
    uint8 step = 0;
    sys_xdata_prof_field_t* p_prof_field = NULL;

    step = XAdProfile_gSrcNibble_1_enable_f - XAdProfile_gSrcNibble_0_enable_f;
    sal_memset(p_field, 0, SYS_XDATA_PROF_FIELD_MAX*sizeof(sys_xdata_prof_field_t));
    do
    {
        p_prof_field = &p_field[loop];
        p_prof_field->width= p_prof->map[loop].width;
        p_prof_field->src_offset= p_prof->map[loop].src_offset;
        p_prof_field->dst_offset= p_prof->map[loop].dst_offset;
        //p_prof_field->flag= p_prof->map[loop].flag;

        switch (p_prof->map[loop].width)
        {
        case CTC_XDATA_WIDTH_16:

            if (p_prof->map[loop].src_offset >= 48) /*nibble*/
            {
                loop2 = 0;
                do
                {
                    src_id = (p_prof->map[loop].src_offset - 48) / CTC_XDATA_WIDTH_4 + loop2;
                    dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_4 + loop2;
                    SetXAdProfile(V, gSrcNibble_0_enable_f + step * src_id, p_profile, 1);
                    SetXAdProfile(V, gSrcNibble_0_destId_f + step * src_id, p_profile, dst_id);
                } while (++loop2 < 4);
            }
            else if (p_prof->map[loop].src_offset >= 32) /*byte*/
            {
                loop2 = 0;
                do
                {
                    src_id = (p_prof->map[loop].src_offset - 32) / CTC_XDATA_WIDTH_8 + loop2;
                    dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_8 + loop2;
                    SetXAdProfile(V, gSrcByte_0_enable_f + step * src_id, p_profile, 1);
                    SetXAdProfile(V, gSrcByte_0_destId_f + step * src_id, p_profile, dst_id);
                } while (++loop2 < 2);
            }
            else /*word*/
            {
                src_id = p_prof->map[loop].src_offset / CTC_XDATA_WIDTH_16;
                dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_16;
                SetXAdProfile(V, gSrcWord_0_enable_f + step * src_id, p_profile, 1);
                SetXAdProfile(V, gSrcWord_0_destId_f + step * src_id, p_profile, dst_id);
            }
            break;
        case CTC_XDATA_WIDTH_8:

            if (p_prof->map[loop].src_offset >= 48) /*nibble*/
            {
                loop2 = 0;
                do
                {
                    src_id = (p_prof->map[loop].src_offset -48) / CTC_XDATA_WIDTH_4 + loop2;
                    dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_4 + loop2;
                    SetXAdProfile(V, gSrcNibble_0_enable_f + step * src_id, p_profile, 1);
                    SetXAdProfile(V, gSrcNibble_0_destId_f + step * src_id, p_profile, dst_id);
                } while (++loop2 < 2);
            }
            else /*byte*/
            {
                src_id = (p_prof->map[loop].src_offset - 32) / CTC_XDATA_WIDTH_8;
                dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_8;
                SetXAdProfile(V, gSrcByte_0_enable_f + step * src_id, p_profile, 1);
                SetXAdProfile(V, gSrcByte_0_destId_f + step * src_id, p_profile, dst_id);
            }
            break;
        case CTC_XDATA_WIDTH_4:

            src_id = (p_prof->map[loop].src_offset - 48) / CTC_XDATA_WIDTH_4;
            dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_4;
            SetXAdProfile(V, gSrcNibble_0_enable_f + step * src_id, p_profile, 1);
            SetXAdProfile(V, gSrcNibble_0_destId_f + step * src_id, p_profile, dst_id);
            break;
        default:
            break;
        }
    } while (++loop < p_prof->num);

    return CTC_E_NONE;
}
STATIC int32
_sys_usw_xdata_fdb_xalu_cfg(uint8 lchip,uint8 dest_offset)
{
    ds_t ds;
    uint32 cmd = 0;
    uint8 shift = 0;

    shift = ((dest_offset % CTC_XDATA_WIDTH_16) >> 2);

    cmd = DRV_IOR(IpeLearningXCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    SetIpeLearningXCtl(V, gXAlu_0_LearningEn_f, &ds, 1);
    SetIpeLearningXCtl(V, gXAlu_0_macLearningEn_f, &ds, 6);
    SetIpeLearningXCtl(V, gXAlu_0_learningRequestEn_f, &ds, 6);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_opType_f, &ds, 1);

    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrc_0_mode_f, &ds, 1);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrc_1_mode_f, &ds, 3);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrc_2_mode_f, &ds, 2);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrcExt_0_wordMask_f, &ds, (0xf << (dest_offset % CTC_XDATA_WIDTH_16)));
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrcExt_1_wordMask_f, &ds, 0xf000);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrcExt_2_wordMask_f, &ds, 0);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrc_0_word_f, &ds, dest_offset / CTC_XDATA_WIDTH_16);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrc_1_word_f, &ds, 3);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrc_2_word_f, &ds, 2);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrc_0_wordRshift_f, &ds, shift);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrc_1_wordRshift_f, &ds, 3);
    SetIpeLearningXCtl(V, gXAlu_0_profile_para_gOpSrc_2_wordRshift_f, &ds, 0);

    cmd = DRV_IOW(IpeLearningXCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_xdata_prof_post_map(uint8 lchip,ctc_xdata_prof_t *p_prof, sys_xdata_prof_field_t* p_field, void *p_profile)
{
    uint8 loop = 0, loop2 = 0;
    uint8 src_id = 0, dst_id = 0;
    uint8 step = 0;
    uint8 is_cid =0;
    uint8 station_move_mode = 0;
    uint8 dest_offset =0;
    sys_xdata_prof_field_t* p_prof_field = NULL;

    step = XAuxProfile_gSrcNibble_1_mode_f - XAuxProfile_gSrcNibble_0_mode_f;
    sal_memset(p_field, 0, SYS_XDATA_PROF_FIELD_MAX*sizeof(sys_xdata_prof_field_t));
    do
    {
        p_prof_field = &p_field[loop];
        p_prof_field->width= p_prof->map[loop].width;
        p_prof_field->src_offset= p_prof->map[loop].src_offset;
        p_prof_field->dst_offset= p_prof->map[loop].dst_offset;
        //p_prof_field->flag= p_prof->map[loop].flag;

        switch (p_prof->map[loop].width)
        {
        case CTC_XDATA_WIDTH_16:
            if (p_prof->map[loop].src_offset >= 112) /*nibble*/
            {
                loop2 = 0;
                do
                {
                    src_id = (p_prof->map[loop].src_offset - 112) / CTC_XDATA_WIDTH_4 + loop2;
                    dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_4 + loop2;
                    SetXAuxProfile(V, gSrcNibble_0_mode_f + step * src_id, p_profile, 1);
                    SetXAuxProfile(V, gSrcNibble_0_destId_f + step * src_id, p_profile, dst_id);
                } while (++loop2 < 4);
            }
            else if (p_prof->map[loop].src_offset >= 64) /*byte*/
            {
                loop2 = 0;
                do
                {
                    src_id = (p_prof->map[loop].src_offset - 64) / CTC_XDATA_WIDTH_8 + loop2;
                    dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_8 + loop2;
                    SetXAuxProfile(V, gSrcByte_0_mode_f + step * src_id, p_profile, 1);
                    SetXAuxProfile(V, gSrcByte_0_destId_f + step * src_id, p_profile, dst_id);
                } while (++loop2 < 2);
            }
            else /*word*/
            {
                src_id = p_prof->map[loop].src_offset / CTC_XDATA_WIDTH_16;
                dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_16;
                SetXAuxProfile(V, gSrcWord_0_mode_f + step * src_id, p_profile, 1);
                SetXAuxProfile(V, gSrcWord_0_destId_f + step * src_id, p_profile, dst_id);
            }
            break;
        case CTC_XDATA_WIDTH_8:

            if (p_prof->map[loop].src_offset >= 112) /*nibble*/
            {
                loop2 = 0;
                do
                {
                    src_id = (p_prof->map[loop].src_offset -112) / CTC_XDATA_WIDTH_4 + loop2;
                    dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_4 + loop2;
                    SetXAuxProfile(V, gSrcNibble_0_mode_f + step * src_id, p_profile, 1);
                    SetXAuxProfile(V, gSrcNibble_0_destId_f + step * src_id, p_profile, dst_id);
                } while (++loop2 < 2);
            }
            else /*byte*/
            {
                src_id = (p_prof->map[loop].src_offset - 64) / CTC_XDATA_WIDTH_8;
                dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_8;
                SetXAuxProfile(V, gSrcByte_0_mode_f + step * src_id, p_profile, 1);
                SetXAuxProfile(V, gSrcByte_0_destId_f + step * src_id, p_profile, dst_id);
            }
            break;
        case CTC_XDATA_WIDTH_4:

            src_id = (p_prof->map[loop].src_offset - 112) / CTC_XDATA_WIDTH_4;
            dst_id = p_prof->map[loop].dst_offset / CTC_XDATA_WIDTH_4;
            SetXAuxProfile(V, gSrcNibble_0_mode_f + step * src_id, p_profile, 1);
            SetXAuxProfile(V, gSrcNibble_0_destId_f + step * src_id, p_profile, dst_id);
            if (src_id==0)
            {
                is_cid = 1;
                dest_offset = p_prof->map[loop].dst_offset;
            }
            break;
        default:
            break;
        }
    } while (++loop < p_prof->num);
    sys_usw_global_get_station_move_mode(lchip, &station_move_mode);
    if (p_prof->type == CTC_XDATA_PROF_TYPE_POST_L3IF && (station_move_mode && is_cid))
    {
        _sys_usw_xdata_fdb_xalu_cfg(lchip,dest_offset);
    }

    return CTC_E_NONE;
}


int32
sys_usw_xdata_prof_build(uint8 lchip, ctc_xdata_prof_t *p_prof, void *p_profile, uint8* dsmet_bmp)
{
    int32 ret = CTC_E_NONE;
    sys_xdata_prof_field_t temp_prof_field[SYS_XDATA_PROF_FIELD_MAX];
    sys_xdata_prof_info_t* p_prof_info = NULL;

    p_prof_info = ctc_vector_get(p_xdata_master[lchip]->prof_vec, SYS_XDATA_ENCODE_PROF_VECTOR_IDX(p_prof->type, p_prof->prof_id));
    if (!p_prof_info)/* set new xad*/
    {
        if(!p_prof->num)/* uset, do nothing */
        {
            return CTC_E_NONE;
        }
        MALLOC_ZERO(MEM_XDATA_MODULE, p_prof_info, sizeof(sys_xdata_prof_info_t))
        if (!p_prof_info)
        {
            return CTC_E_NO_MEMORY;
        }
    }
    else
    {
        if (0 == p_prof->num)/* uset xad*/
        {
            sal_memset(p_profile, 0, sizeof(ds1_t));/* use to clear hw tbl*/
            ctc_vector_del(p_xdata_master[lchip]->prof_vec, SYS_XDATA_ENCODE_PROF_VECTOR_IDX(p_prof->type, p_prof->prof_id));
            mem_free(p_prof_info);
            CTC_BIT_UNSET(p_xdata_master[lchip]->prof_bmp[p_prof->type], p_prof->prof_id);
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PROF, 1);
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_MASTER, 1);
            return CTC_E_NONE;
        }
        else/* check entry exist*/
        {
            return CTC_E_ENTRY_EXIST;
        }
    }

    if(p_prof->type == SYS_XDATA_PROF_TYPE_DSMET)
    {
        _sys_usw_xdata_prof_dsmet_map(lchip, p_prof,temp_prof_field, p_profile, dsmet_bmp);
    }
    else if(p_prof->type < CTC_XDATA_PROF_TYPE_POST_MAX)
    {
        _sys_usw_xdata_prof_post_map(lchip, p_prof,temp_prof_field, p_profile);
    }
    else
    {
        _sys_usw_xdata_prof_ad_map(lchip, p_prof,temp_prof_field, p_profile);
    }

    sal_memcpy(p_prof_info->field, temp_prof_field, p_prof->num*sizeof(sys_xdata_prof_field_t));
    p_prof_info->num = p_prof->num;
    if (FALSE == ctc_vector_add(p_xdata_master[lchip]->prof_vec, SYS_XDATA_ENCODE_PROF_VECTOR_IDX(p_prof->type, p_prof->prof_id), p_prof_info))
    {
        ret = CTC_E_NO_MEMORY;
        goto error0;
    }
    CTC_BIT_SET(p_xdata_master[lchip]->prof_bmp[p_prof->type], p_prof->prof_id);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PROF, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_MASTER, 1);
    return CTC_E_NONE;

error0:
    mem_free(p_prof_info);
    return ret;

}

int32
_sys_usw_xdata_set_profile(uint8 lchip, ctc_xdata_prof_t* p_prof)
{
    ds1_t control;
    ds1_t profile;
    uint32 cmd = 0;
    uint32 table_id = 0, field_id = 0, field2_id = 0xffffffff;
    uint8 step = 0;
    uint8 dsmet_bmp = 0;

    sal_memset(&profile, 0, sizeof(ds1_t));

    /* 1. param check */
    CTC_ERROR_RETURN(_sys_usw_xdata_prof_param_check(lchip, p_prof));

    /* 2. build xdata profile */
    CTC_ERROR_RETURN(sys_usw_xdata_prof_build(lchip, p_prof, (void *)&profile, &dsmet_bmp));

    /* 3. get write tbl info */
    switch (p_prof->type)
    {
    case CTC_XDATA_PROF_TYPE_DSSCL:
        table_id = IpeUserIdXCtl_t;
        step = IpeUserIdXCtl_gXAd_1_profile_f - IpeUserIdXCtl_gXAd_0_profile_f;
        field_id = IpeUserIdXCtl_gXAd_0_profile_f + step * p_prof->prof_id;
        break;
    case CTC_XDATA_PROF_TYPE_DSTUNNEL:
        table_id = IpeTunnelDecapXCtl_t;
        step = IpeTunnelDecapXCtl_gXAd_1_profile_f - IpeTunnelDecapXCtl_gXAd_0_profile_f;
        field_id = IpeTunnelDecapXCtl_gXAd_0_profile_f + step * p_prof->prof_id;
        break;
    case CTC_XDATA_PROF_TYPE_DSMPLS:
        table_id = IpeMplsXCtl_t;
        field_id = IpeMplsXCtl_xLbHashNibble_f;
        cmd = DRV_IOR(table_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &control);
        DRV_SET_FIELD_V(lchip, table_id, field_id, &control, p_prof->num? p_prof->map[0].dst_offset/CTC_XDATA_WIDTH_4 : 0 );/* add or remove */
        cmd = DRV_IOW(table_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &control);
        return CTC_E_NONE;
    case CTC_XDATA_PROF_TYPE_DSMACDA:
        table_id = IpeBridgeXCtl_t;
        step = IpeBridgeXCtl_gXAd_1_profile_f - IpeBridgeXCtl_gXAd_0_profile_f;
        field_id = IpeBridgeXCtl_gXAd_0_profile_f + step * p_prof->prof_id;
        break;
#if 0
    case CTC_XDATA_PROF_TYPE_DSMACSA:
        table_id = IpeLearningXCtl_t;
        step = IpeLearningXCtl_gXAd_1_profile_f - IpeLearningXCtl_gXAd_0_profile_f;
        field_id = IpeLearningXCtl_gXAd_0_profile_f + step * p_prof->prof_id; /*default use 1*/
        break;
#endif
    case CTC_XDATA_PROF_TYPE_DSIPDA:
        table_id = IpeRouteXCtl_t;
        field_id = IpeRouteXCtl_gXAd_0_profile_f;
        break;
#if 0
    case CTC_XDATA_PROF_TYPE_DSIPSA:
        table_id = IpeRouteXCtl_t;
        field_id = IpeRouteXCtl_gXAd_1_profile_f;
        break;
#endif
    case CTC_XDATA_PROF_TYPE_DSFLOW:
        table_id = IpeFlowHashXCtl_t;
        step = IpeFlowHashXCtl_gXAd_1_profile_f - IpeFlowHashXCtl_gXAd_0_profile_f;
        field_id = IpeFlowHashXCtl_gXAd_0_profile_f + step * p_prof->prof_id;
        break;
    case CTC_XDATA_PROF_TYPE_DSACL:
        table_id = IpeFwdAclXCtl_t;
        step = IpeFwdAclXCtl_gXAd_1_profile_f - IpeFwdAclXCtl_gXAd_0_profile_f;
        field_id = IpeFwdAclXCtl_gXAd_0_profile_f + step * p_prof->prof_id;
        break;
#if 0
    case CTC_XDATA_PROF_TYPE_DSNEXTHOP:
#endif
    case CTC_XDATA_PROF_TYPE_EGS_DSSCL:
        table_id = EpeNextHopXCtl_t;
        step = EpeNextHopXCtl_gXAd_1_profile_f - EpeNextHopXCtl_gXAd_0_profile_f;
        field_id = EpeNextHopXCtl_gXAd_0_profile_f + step * p_prof->prof_id;
        break;
    case CTC_XDATA_PROF_TYPE_EGS_DSACL:
        table_id = EpeAclQosXCtl_t;
        step = EpeAclQosXCtl_gXAd_1_profile_f - EpeAclQosXCtl_gXAd_0_profile_f;
        field_id = EpeAclQosXCtl_gXAd_0_profile_f + step * p_prof->prof_id;
        break;
    case SYS_XDATA_PROF_TYPE_DSMET:
        table_id = MetFifoXCtl_t;
        step = MetFifoXCtl_gXHeaderExt_1_profile_f - MetFifoXCtl_gXHeaderExt_0_profile_f;
        field_id = MetFifoXCtl_gXHeaderExt_0_profile_f + step * p_prof->prof_id;
        break;
    case CTC_XDATA_PROF_TYPE_POST_SCL:
        table_id = IpeUserIdXCtl_t;
        field_id = IpeUserIdXCtl_xProcAuxProfile_f;
        field2_id = IpeUserIdXCtl_disableXPI_f;
        break;
    case CTC_XDATA_PROF_TYPE_POST_L3IF:
        table_id = IpeIntfMapperXCtl_t;
        field_id = IpeIntfMapperXCtl_xProcAuxProfile_f;
        field2_id = IpeIntfMapperXCtl_disableXPI_f;
        break;
    case CTC_XDATA_PROF_TYPE_POST_TUNNEL:
        table_id = IpeTunnelDecapXCtl_t;
        field_id = IpeTunnelDecapXCtl_xProcAuxProfile_f;
        field2_id = IpeTunnelDecapXCtl_disableXPI_f;
        break;
    case CTC_XDATA_PROF_TYPE_POST_FWD:
        table_id = IpePktProcXCtl_t;
        field_id = IpePktProcXCtl_xAuxProfile_f;
        field2_id = IpePktProcXCtl_disableXPI_f;
        break;
    case CTC_XDATA_PROF_TYPE_POST_ACL:
        table_id = IpeFwdAclXCtl_t;
        field_id = IpeFwdAclXCtl_xAuxProfile_f;
        field2_id = IpeFwdAclXCtl_disableXPI_f;
        break;
    default:
        return CTC_E_NOT_SUPPORT;
    }
    /* 4. write tbl */
    cmd = DRV_IOR(table_id, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &control);
    DRV_SET_FIELD_A(lchip, table_id, field_id, &control, &profile);
    DRV_SET_FIELD_V(lchip, table_id, field2_id, &control, p_prof->num ? 0 : 1);/* add or remove */
    cmd = DRV_IOW(table_id, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &control);
    if(SYS_XDATA_PROF_TYPE_DSMET == p_prof->type)
    {
        step = PreBufferRetrieveXCtl_gXHeader_1_nibbleEn_f - PreBufferRetrieveXCtl_gXHeader_0_nibbleEn_f;
        field_id = PreBufferRetrieveXCtl_gXHeader_0_nibbleEn_f+step * p_prof->prof_id;
        table_id = PreBufferRetrieveXCtl_t;
        cmd = DRV_IOR(table_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &control);
        DRV_SET_FIELD_V(lchip, table_id, field_id, &control, p_prof->num ? dsmet_bmp : 0);/* add or remove */
        cmd = DRV_IOW(table_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &control);
    }
    return CTC_E_NONE;
}

int32
_sys_usw_xdata_get_profile(uint8 lchip, ctc_xdata_prof_t* p_prof)
{
    sys_xdata_prof_info_t* p_prof_info = NULL;
    uint8 loop = 0;

    CTC_MAX_VALUE_CHECK(p_prof->type, CTC_XDATA_PROF_TYPE_MAX);

    p_prof_info = ctc_vector_get(p_xdata_master[lchip]->prof_vec, SYS_XDATA_ENCODE_PROF_VECTOR_IDX(p_prof->type, p_prof->prof_id));
    if (!p_prof_info)
    {
        return CTC_E_ENTRY_NOT_EXIST;
    }
    p_prof->num = p_prof_info->num;
    for(loop = 0; loop < p_prof_info->num; loop++)
    {
        p_prof->map[loop].width = p_prof_info->field[loop].width;
        p_prof->map[loop].src_offset = p_prof_info->field[loop].src_offset;
        p_prof->map[loop].dst_offset = p_prof_info->field[loop].dst_offset;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_xdata_path_set_fixed_field(uint8 lchip, ctc_xdata_path_t *p_path, uint32* p_valid_bmp, void* control, void* profile)
{
    uint8 step = 0;
    uint8 step1 = 0;
    uint8 value = 0;
    uint32 cmd = 0;
    uint32 control_tbl[CTC_XDATA_PATH_TYPE_MAX] = {IpeFwdXCtl_t,IpeFwdXCtl_t,
        EpeHdrAdjustXCtl_t,EpeHeaderEditXCtl_t,EpeHeaderEditXCtl_t,IpeHeaderAdjustXCtl_t,IpeHeaderAdjustXCtl_t};

    cmd = DRV_IOR(control_tbl[p_path->type], DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, control);

    sal_memset(profile, 0, sizeof(ds1_t));
    switch (p_path->type)
    {
        case CTC_XDATA_PATH_TYPE_IPE_BSR:
            step = IpeFwdXCtl_gXHeader_1_editAuxDataEn_f - IpeFwdXCtl_gXHeader_0_editAuxDataEn_f;
            step = step*p_path->prof_id;

            SetIpeFwdXCtl(V, gXHeader_0_editAuxDataEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT) ? 0xF : 0;
            SetIpeFwdXCtl(V, gXHeader_0_symmetricEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_HASH_VALUE));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_HASH_VALUE) ? (0x3 << 4) : 0;
            SetIpeFwdXCtl(V, gXHeader_0_naptEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_NAT_L4_SRC_PORT));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_NAT_L4_SRC_PORT)? (0xF << 4) : 0;
            SetIpeFwdXCtl(V, gXHeader_0_entropEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH) ? (0x3 << 6) :0;
            value = GetIpeFwdXCtl(V, gXHeader_0_naptEn_f + step, control);
            value |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_NAT_L4_DST_PORT) ? 0x2 : 0;
            SetIpeFwdXCtl(V, gXHeader_0_naptEn_f + step, control, value);
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_NAT_L4_DST_PORT) ? (0xF << 8) :0;
            SetIpeFwdXCtl(V, gXHeader_0_apsFlagEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_APS_PROTECTING_EN));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_APS_PROTECTING_EN) ? (0x1 << 13):0;
            SetIpeFwdXCtl(V, gXHeader_0_fwdTypeEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_FWD_TYPE));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_FWD_TYPE) ? (0x1 << 14):0;
            break;
        case CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR:
            step = IpeFwdXCtl_gXHeader_1_editAuxDataEn_f - IpeFwdXCtl_gXHeader_0_editAuxDataEn_f;
            step = step*p_path->prof_id;

            SetIpeFwdXCtl(V, gXHeader_0_naptEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_L3IF_ID));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_L3IF_ID) ? (0xF << 4):0;
            SetIpeFwdXCtl(V, gXHeader_0_editAuxDataEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_EFD));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_EFD) ? (0xF << 4) :0;
            SetIpeFwdXCtl(V, gXHeader_0_symmetricEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_HASH_VALUE));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_HASH_VALUE) ? (0x3 << 8) :0;
            SetIpeFwdXCtl(V, gXHeader_0_entropEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH) ? (0x3 << 10) :0;
            break;
        case CTC_XDATA_PATH_TYPE_BSR_EPE:
            step = EpeHdrAdjustXCtl_gXHeader_1_fwdTypeEn_f - EpeHdrAdjustXCtl_gXHeader_0_fwdTypeEn_f;
            step1 = step;
            step = step*p_path->prof_id;
            {
                uint8 loop = 0;
                uint8 src_id = 0;
                uint8 dst_id = SYS_XDATA_PATH_LOGIC_PORT_EXT_POS/CTC_XDATA_WIDTH_4;

                do
                {
                    if(CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT))
                    {
                        CTC_BIT_SET(*p_valid_bmp, dst_id);
                    }
                    SetXHeader2XPIProfile(V, gSrcNibbleEn_0_nibbleEn_f + step1 * src_id, profile, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT));
                    SetXHeader2XPIProfile(V, gSrcNibbleExt_0_destNibbleHigh_f + step1 * src_id, profile, dst_id >> 4);
                    SetXHeader2XPIProfile(V, gSrcNibble_0_destNibble_f + step1 * src_id, profile, dst_id & 0xF);
                    src_id++;
                    dst_id++;
                }while (++loop < 4);
            }
            SetEpeHdrAdjustXCtl(V, gXHeader_0_fwdTypeEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_FWD_TYPE));
            SetEpeHdrAdjustXCtl(V, gXHeader_0_apsFlagEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_APS_PROTECTING_EN));
            SetEpeHdrAdjustXCtl(V, gXHeader_0_entropEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH));
            SetEpeHdrAdjustXCtl(V, gXHeader_0_naptEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_NAT_L4_SRC_PORT));
            SetEpeHdrAdjustXCtl(V, gXHeader_0_symmetricEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_HASH_VALUE));
            value = GetEpeHdrAdjustXCtl(V, gXHeader_0_naptEn_f + step, control);
            value |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_NAT_L4_DST_PORT) ? 0x2 :0;
            SetEpeHdrAdjustXCtl(V, gXHeader_0_naptEn_f + step, control, value);

            break;
        case CTC_XDATA_PATH_TYPE_EPE_LOOP0:
            break;
        case CTC_XDATA_PATH_TYPE_EPE_LOOP1:
            step = EpeHeaderEditXCtl_gXHeader_1_profile_f - EpeHeaderEditXCtl_gXHeader_0_profile_f;
            step = step*p_path->prof_id;
            SetEpeHeaderEditXCtl(V, gXHeader_0_ingressEn_f + step, control, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_INGRESS_EN));
            *p_valid_bmp |= CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_INGRESS_EN)?0xFFF:0;
            break;
        case CTC_XDATA_PATH_TYPE_LOOP0_IPE:
        case CTC_XDATA_PATH_TYPE_LOOP1_IPE:
            break;
        default:
            return CTC_E_NOT_SUPPORT;
            break;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_xdata_path_set_profile(uint8 lchip, ctc_xdata_path_t *p_path, uint32* p_valid_bmp, sys_xdata_path_field_t* p_path_field, void* profile)
{
    uint8 loop = 0, loop2 = 0;
    uint8 src_id = 0, dst_id = 0;
    uint8 step = 0;
    sys_xdata_path_field_t* path_field = NULL;

    switch (p_path->type)
    {
        case CTC_XDATA_PATH_TYPE_IPE_BSR:
        case CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR:
        case CTC_XDATA_PATH_TYPE_EPE_LOOP0:
        case CTC_XDATA_PATH_TYPE_EPE_LOOP1:
            step = XPI2XHeaderProfile_gDestNibbleEn_1_nibbleEn_f - XPI2XHeaderProfile_gDestNibbleEn_0_nibbleEn_f;
            for (loop = 0; loop < p_path->num; loop++)
            {
                path_field = &p_path_field[loop];
                path_field->width = p_path->map[loop].width;
                path_field->dst_offset = p_path->map[loop].dst_offset;
                path_field->src_offset = p_path->map[loop].src_offset;

                src_id = p_path->map[loop].src_offset / CTC_XDATA_WIDTH_4;
                dst_id = p_path->map[loop].dst_offset / CTC_XDATA_WIDTH_4;
                loop2 = 0;
                do
                {
                    if (CTC_IS_BIT_SET(*p_valid_bmp, dst_id))
                    {
                        return CTC_E_PARAM_CONFLICT;
                    }
                    CTC_BIT_SET(*p_valid_bmp, dst_id);
                    SetXPI2XHeaderProfile(V, gDestNibbleEn_0_nibbleEn_f + step * dst_id, profile, 1);
                    SetXPI2XHeaderProfile(V, gDestNibbleExt_0_srcNibbleHigh_f + step * dst_id, profile, src_id >> 4);
                    SetXPI2XHeaderProfile(V, gDestNibble_0_srcNibble_f + step * dst_id, profile, src_id & 0xF);
                    src_id++;
                    dst_id++;
                } while (++loop2 < p_path->map[loop].width / CTC_XDATA_WIDTH_4);
            }
            break;

        case CTC_XDATA_PATH_TYPE_BSR_EPE:
        case CTC_XDATA_PATH_TYPE_LOOP0_IPE:
        case CTC_XDATA_PATH_TYPE_LOOP1_IPE:
            step = XHeader2XPIProfile_gSrcNibbleEn_1_nibbleEn_f - XHeader2XPIProfile_gSrcNibbleEn_0_nibbleEn_f;
            for (loop = 0; loop < p_path->num; loop++)
            {
                path_field = &p_path_field[loop];
                path_field->width = p_path->map[loop].width;
                path_field->dst_offset = p_path->map[loop].dst_offset;
                path_field->src_offset = p_path->map[loop].src_offset;

                src_id = p_path->map[loop].src_offset / CTC_XDATA_WIDTH_4;
                dst_id = p_path->map[loop].dst_offset / CTC_XDATA_WIDTH_4;
                loop2 = 0;
                do
                {
                    if (CTC_IS_BIT_SET(*p_valid_bmp, dst_id))
                    {
                        return CTC_E_PARAM_CONFLICT;
                    }
                    CTC_BIT_SET(*p_valid_bmp, dst_id);
                    SetXHeader2XPIProfile(V, gSrcNibbleEn_0_nibbleEn_f + step * src_id, profile, 1);
                    SetXHeader2XPIProfile(V, gSrcNibbleExt_0_destNibbleHigh_f + step * src_id, profile, dst_id >> 4);
                    SetXHeader2XPIProfile(V, gSrcNibble_0_destNibble_f + step * src_id, profile, dst_id & 0xF);
                    src_id++;
                    dst_id++;
                } while (++loop2 < p_path->map[loop].width / CTC_XDATA_WIDTH_4);
            }

            break;
        default:
            return CTC_E_NOT_SUPPORT;
            break;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_xdata_path_add_hw(uint8 lchip, ctc_xdata_path_t *p_path, void* control, void* profile, uint8 is_uset)
{
    uint8 step = 0;
    uint32 cmd = 0;
    uint32 xcf_en = 0;
    uint8 logic_port_ext_bmp = 0;
    EpeNextHopXCtl_m ds;

    switch (p_path->type)
    {
        case CTC_XDATA_PATH_TYPE_IPE_BSR:
            step = IpeFwdXCtl_gXHeader_1_profile_f - IpeFwdXCtl_gXHeader_0_profile_f;
            step = step*p_path->prof_id;
            if(is_uset)
            {
                cmd = DRV_IOR(IpeFwdXCtl_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, 0, cmd, control);
                sal_memset(profile, 0, sizeof(ds1_t));
                SetIpeFwdXCtl(V, gXHeader_0_editAuxDataEn_f + step, control, 0);
                SetIpeFwdXCtl(V, gXHeader_0_symmetricEn_f + step, control, 0);
                SetIpeFwdXCtl(V, gXHeader_0_naptEn_f + step, control, 0);
                SetIpeFwdXCtl(V, gXHeader_0_entropEn_f + step,control, 0);
                SetIpeFwdXCtl(V, gXHeader_0_apsFlagEn_f + step, control, 0);
                SetIpeFwdXCtl(V, gXHeader_0_fwdTypeEn_f + step, control, 0);
            }
            DRV_SET_FIELD_A(lchip, IpeFwdXCtl_t, IpeFwdXCtl_gXHeader_0_profile_f + step, control, profile);
            xcf_en = GetIpeFwdXCtl(V, xCFTypeEn_f, control);
            if (CTC_FLAG_ISSET(p_path->flag, CTC_XDATA_PATH_STACKING_EN))
            {
                CTC_BIT_SET(xcf_en, p_path->prof_id);
            }
            else
            {
                CTC_BIT_UNSET(xcf_en, p_path->prof_id);
            }
            SetIpeFwdXCtl(V, xCFTypeEn_f, control, xcf_en);
            cmd = DRV_IOW(IpeFwdXCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, control);
            cmd = DRV_IOW(IpeHeaderAdjustXCtl_t, IpeHeaderAdjustXCtl_xCFTypeEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &xcf_en));
            cmd = DRV_IOW(EpeHeaderEditXCtl_t, EpeHeaderEditXCtl_xCFHeaderTypeEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &xcf_en));
            break;
        case CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR:
            step = IpeFwdXCtl_gXHeader_1_profile_f - IpeFwdXCtl_gXHeader_0_profile_f;
            step = step*p_path->prof_id;
            if(is_uset)
            {
                cmd = DRV_IOR(IpeFwdXCtl_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, 0, cmd, control);
                sal_memset(profile, 0, sizeof(ds1_t));
                SetIpeFwdXCtl(V, gXHeader_0_editAuxDataEn_f + step, control, 0);
                SetIpeFwdXCtl(V, gXHeader_0_symmetricEn_f + step, control, 0);
                SetIpeFwdXCtl(V, gXHeader_0_naptEn_f + step, control, 0);
                SetIpeFwdXCtl(V, gXHeader_0_entropEn_f + step, control, 0);
            }
            DRV_SET_FIELD_A(lchip, IpeFwdXCtl_t, IpeFwdXCtl_gXHeader_0_profile_f + step,control, profile);
            cmd = DRV_IOW(IpeFwdXCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, control);
            break;
        case CTC_XDATA_PATH_TYPE_BSR_EPE:
            step = EpeHdrAdjustXCtl_gXHeader_1_profile_f - EpeHdrAdjustXCtl_gXHeader_0_profile_f;
            step = step*p_path->prof_id;
            if(is_uset)
            {
                cmd = DRV_IOR(EpeHdrAdjustXCtl_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, 0, cmd, control);
                sal_memset(profile, 0, sizeof(ds1_t));
                SetEpeHdrAdjustXCtl(V, gXHeader_0_fwdTypeEn_f + step, control,0);
                SetEpeHdrAdjustXCtl(V, gXHeader_0_apsFlagEn_f + step, control, 0);
                SetEpeHdrAdjustXCtl(V, gXHeader_0_entropEn_f + step, control, 0);
                SetEpeHdrAdjustXCtl(V, gXHeader_0_naptEn_f + step, control, 0);
                SetEpeHdrAdjustXCtl(V, gXHeader_0_symmetricEn_f + step, control, 0);
            }
            cmd = DRV_IOR(EpeNextHopXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            logic_port_ext_bmp = p_xdata_master[lchip]->logic_port_ext_bmp;
            CTC_BIT_UNSET(logic_port_ext_bmp, p_path->prof_id);
            if(!logic_port_ext_bmp)
            {
                SetEpeNextHopXCtl(V, logicPortExtSelEn_f, &ds, CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT));
                SetEpeNextHopXCtl(V, logicPortExtSel_f, &ds, SYS_XDATA_PATH_LOGIC_PORT_EXT_POS/CTC_XDATA_WIDTH_16);
            }
            cmd = DRV_IOW(EpeNextHopXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            DRV_SET_FIELD_A(lchip, EpeHdrAdjustXCtl_t, EpeHdrAdjustXCtl_gXHeader_0_profile_f + step,control, profile);
            cmd = DRV_IOW(EpeHdrAdjustXCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, control);
            break;
        case CTC_XDATA_PATH_TYPE_EPE_LOOP0:
            step = EpeHeaderEditXCtl_gXHeader_1_profile_f - EpeHeaderEditXCtl_gXHeader_0_profile_f;
            step = step*p_path->prof_id;
            if(is_uset)
            {
                cmd = DRV_IOR(EpeHeaderEditXCtl_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, 0, cmd, control);
                sal_memset(profile, 0, sizeof(ds1_t));
            }
            DRV_SET_FIELD_A(lchip, EpeHeaderEditXCtl_t, EpeHeaderEditXCtl_gXHeader_0_profile_f + step,control, profile);
            cmd = DRV_IOW(EpeHeaderEditXCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, control);

            break;
        case CTC_XDATA_PATH_TYPE_EPE_LOOP1:
            step = EpeHeaderEditXCtl_gXHeader_1_profile_f - EpeHeaderEditXCtl_gXHeader_0_profile_f;
            step = step*p_path->prof_id;
            if(is_uset)
            {
                cmd = DRV_IOR(EpeHeaderEditXCtl_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, 0, cmd, control);
                sal_memset(profile, 0, sizeof(ds1_t));
                SetEpeHeaderEditXCtl(V, gXHeader_0_ingressEn_f + step, control, 0);
            }
            DRV_SET_FIELD_A(lchip, EpeHeaderEditXCtl_t, EpeHeaderEditXCtl_gXHeader_0_profile_f + step,control, profile);
            cmd = DRV_IOW(EpeHeaderEditXCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, control);

            break;
        case CTC_XDATA_PATH_TYPE_LOOP0_IPE:
        case CTC_XDATA_PATH_TYPE_LOOP1_IPE:
            step = IpeHeaderAdjustXCtl_gXHeader_1_profile_f - IpeHeaderAdjustXCtl_gXHeader_0_profile_f;
            step = step*p_path->prof_id;
            if(is_uset)
            {
                cmd = DRV_IOR(IpeHeaderAdjustXCtl_t, DRV_ENTRY_FLAG);
                DRV_IOCTL(lchip, 0, cmd, control);
                sal_memset(profile, 0, sizeof(ds1_t));
            }
            DRV_SET_FIELD_A(lchip, IpeHeaderAdjustXCtl_t, IpeHeaderAdjustXCtl_gXHeader_0_profile_f + step,control, profile);
            cmd = DRV_IOW(IpeHeaderAdjustXCtl_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, 0, cmd, control);

            break;
        default:
            return CTC_E_NOT_SUPPORT;
            break;
    }
    return CTC_E_NONE;
}

int32
_sys_usw_xdata_path_build(uint8 lchip, ctc_xdata_path_t *p_path)
{
    int32 ret = CTC_E_NONE;
    uint32 valid_bmp = 0;
    uint8 is_uset = 0;
    uint8 is_add  = 0;
    ds1_t control;
    ds1_t profile;
    sys_xdata_path_field_t temp_path_field[SYS_XDATA_PATH_FIELD_MAX];
    sys_xdata_path_info_t* p_path_info = NULL;

    /* 1. get path info or uset old */
    is_uset = (!p_path->num && !p_path->fixed_bmp && !p_path->flag)? 1: 0;
    p_path_info = ctc_vector_get(p_xdata_master[lchip]->path_vec, SYS_XDATA_ENCODE_PATH_VECTOR_IDX(p_path->type, p_path->prof_id));
    if (!p_path_info)/* set new xad*/
    {
        if (is_uset)
        {/* do nothing*/
            return CTC_E_NONE;
        }
        MALLOC_ZERO(MEM_XDATA_MODULE, p_path_info, sizeof(sys_xdata_path_info_t))
        if (!p_path_info)
        {
            return CTC_E_NO_MEMORY;
        }
        is_add = 1;
    }
    else
    {
        if (is_uset)/* uset path*/
        {
            ctc_vector_del(p_xdata_master[lchip]->path_vec, SYS_XDATA_ENCODE_PROF_VECTOR_IDX(p_path->type, p_path->prof_id));
            mem_free(p_path_info);
            CTC_BIT_UNSET(p_xdata_master[lchip]->path_bmp[p_path->type], p_path->prof_id);
            _sys_usw_xdata_path_add_hw(lchip, p_path, &control, &profile, is_uset);
            if(CTC_XDATA_PATH_TYPE_BSR_EPE == p_path->type)
            {
                CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT) ? CTC_BIT_SET(p_xdata_master[lchip]->logic_port_ext_bmp, p_path->prof_id) :
                                                                                           CTC_BIT_UNSET(p_xdata_master[lchip]->logic_port_ext_bmp, p_path->prof_id);
            }
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_MASTER, 1);
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PATH, 1);
            return CTC_E_NONE;
        }
    }

    /* 2. set and check fixed field */
    _sys_usw_xdata_path_set_fixed_field(lchip, p_path, &valid_bmp, &control, &profile);

    /* 3. set and check path profile */
    sal_memset(temp_path_field, 0, SYS_XDATA_PATH_FIELD_MAX*sizeof(sys_xdata_path_field_t));
    CTC_ERROR_GOTO(_sys_usw_xdata_path_set_profile(lchip, p_path, &valid_bmp, temp_path_field, &profile), ret, error0);

    /* 4. write hw */
    _sys_usw_xdata_path_add_hw(lchip, p_path, &control, &profile, is_uset);

    /* 5. add sw*/
    sal_memcpy(p_path_info->field, temp_path_field, p_path->num*sizeof(sys_xdata_path_field_t));
    if (is_add && FALSE == ctc_vector_add(p_xdata_master[lchip]->path_vec, SYS_XDATA_ENCODE_PATH_VECTOR_IDX(p_path->type, p_path->prof_id), p_path_info))
    {
        ret = CTC_E_NO_MEMORY;
        goto error0;
    }
    p_path_info->num = p_path->num;
    p_path_info->valid_bmp = valid_bmp;
    p_path_info->fixed_bmp = p_path->fixed_bmp;
    if(CTC_XDATA_PATH_TYPE_BSR_EPE == p_path->type)
    {
        CTC_FLAG_ISSET(p_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT) ? CTC_BIT_SET(p_xdata_master[lchip]->logic_port_ext_bmp, p_path->prof_id) :
                                                                                   CTC_BIT_UNSET(p_xdata_master[lchip]->logic_port_ext_bmp, p_path->prof_id);
    }
    CTC_BIT_SET(p_xdata_master[lchip]->path_bmp[p_path->type], p_path->prof_id);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_MASTER, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PATH, 1);
    return CTC_E_NONE;

error0:
    if (is_add)
    {
        mem_free(p_path_info);
    }
    return ret;
}

STATIC int32
_sys_usw_xdata_path_check_param(uint8 lchip, ctc_xdata_path_t* p_path)
{
    uint8 loop = 0;
    uint8 src_band[CTC_XDATA_PATH_TYPE_MAX] = {128,128,64,128,128,64,64};
    uint8 dst_band[CTC_XDATA_PATH_TYPE_MAX] = {64,64,128,64,64,128,128};
    uint16 fixed_bmp[CTC_XDATA_PATH_TYPE_MAX] = {0x7F,0x18A,0x7F,0,0x400,0,0};

    CTC_MAX_VALUE_CHECK(p_path->type, CTC_XDATA_PATH_TYPE_MAX-1);
    CTC_MAX_VALUE_CHECK(p_path->num, SYS_XDATA_PATH_FIELD_MAX);
    if (fixed_bmp[p_path->type] != (p_path->fixed_bmp | fixed_bmp[p_path->type]))
    {
        return CTC_E_PARAM_CONFLICT;
    }

    /* check profile id and fiexd field base CTC_XDATA_PATH_TYPE_XXX*/
    switch (p_path->type)
    {
        case CTC_XDATA_PATH_TYPE_IPE_BSR:
            CTC_MAX_VALUE_CHECK(p_path->prof_id, CTC_CONST8-1)
            if (CTC_IS_BIT_SET(p_xdata_master[lchip]->path_bmp[CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR], p_path->prof_id))
            {
                return CTC_E_IN_USE;
            }
            if(CTC_FLAG_ISSET(p_path->fixed_bmp,CTC_XDATA_FIXED_FIELD_NAT_L4_SRC_PORT) && 
              (CTC_FLAG_ISSET(p_path->fixed_bmp,CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH) ||
               CTC_FLAG_ISSET(p_path->fixed_bmp,CTC_XDATA_FIXED_FIELD_HASH_VALUE)))
            {
                return CTC_E_PARAM_CONFLICT;
            }
            break;
        case CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR:
            CTC_MAX_VALUE_CHECK(p_path->prof_id, CTC_CONST8-1);
            if (CTC_IS_BIT_SET(p_xdata_master[lchip]->path_bmp[CTC_XDATA_PATH_TYPE_IPE_BSR], p_path->prof_id))
            {
                return CTC_E_IN_USE;
            }
            break;
        case CTC_XDATA_PATH_TYPE_BSR_EPE:
            CTC_MAX_VALUE_CHECK(p_path->prof_id, CTC_CONST8-1);
            if(CTC_FLAG_ISSET(p_path->fixed_bmp,CTC_XDATA_FIXED_FIELD_NAT_L4_SRC_PORT) && 
              (CTC_FLAG_ISSET(p_path->fixed_bmp,CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH) ||
               CTC_FLAG_ISSET(p_path->fixed_bmp,CTC_XDATA_FIXED_FIELD_HASH_VALUE)))
            {
                return CTC_E_PARAM_CONFLICT;
            }

            break;
        case CTC_XDATA_PATH_TYPE_EPE_LOOP0:
            CTC_MAX_VALUE_CHECK(p_path->prof_id, 3);
            if (CTC_IS_BIT_SET(p_xdata_master[lchip]->path_bmp[CTC_XDATA_PATH_TYPE_EPE_LOOP1], p_path->prof_id))
            {
                return CTC_E_IN_USE;
            }
            break;
        case CTC_XDATA_PATH_TYPE_EPE_LOOP1:
            CTC_MAX_VALUE_CHECK(p_path->prof_id, 3);
            if (CTC_IS_BIT_SET(p_xdata_master[lchip]->path_bmp[CTC_XDATA_PATH_TYPE_EPE_LOOP0], p_path->prof_id))
            {
                return CTC_E_IN_USE;
            }
            break;
        case CTC_XDATA_PATH_TYPE_LOOP0_IPE:
            CTC_MAX_VALUE_CHECK(p_path->prof_id, CTC_CONST8-1);
            if (CTC_IS_BIT_SET(p_xdata_master[lchip]->path_bmp[CTC_XDATA_PATH_TYPE_LOOP1_IPE], p_path->prof_id))
            {
                return CTC_E_IN_USE;
            }
            break;
        case CTC_XDATA_PATH_TYPE_LOOP1_IPE:
            CTC_MAX_VALUE_CHECK(p_path->prof_id, CTC_CONST8-1);
            if (CTC_IS_BIT_SET(p_xdata_master[lchip]->path_bmp[CTC_XDATA_PATH_TYPE_LOOP0_IPE], p_path->prof_id))
            {
                return CTC_E_IN_USE;
            }

            break;
        default:
            return CTC_E_NOT_SUPPORT;
            break;

    }

    /* 2. check offset */
    for (loop = 0; loop < p_path->num; loop++)
    {
        if ((p_path->map[loop].src_offset + p_path->map[loop].width) > src_band[p_path->type] || 0 != (p_path->map[loop].src_offset % 4) ||
            (p_path->map[loop].dst_offset + p_path->map[loop].width) > dst_band[p_path->type] || 0 != (p_path->map[loop].dst_offset % 4) ||
            (p_path->map[loop].width != CTC_XDATA_WIDTH_4 && p_path->map[loop].width != CTC_XDATA_WIDTH_8 && p_path->map[loop].width != CTC_XDATA_WIDTH_16))
        {
            return CTC_E_INVALID_PARAM;
        }
    }

    return CTC_E_NONE;

}

int32
_sys_usw_xdata_set_path(uint8 lchip, ctc_xdata_path_t* p_path)
{
    /* 1. check param */
    CTC_ERROR_RETURN(_sys_usw_xdata_path_check_param(lchip, p_path));

    /* 2. build xdata path */
    CTC_ERROR_RETURN(_sys_usw_xdata_path_build(lchip, p_path));

    return CTC_E_NONE;
}


int32
_sys_usw_xdata_get_path(uint8 lchip, ctc_xdata_path_t* p_path)
{
    sys_xdata_path_info_t* p_path_info = NULL;
    uint8 loop = 0;

    CTC_MAX_VALUE_CHECK(p_path->type, CTC_XDATA_PATH_TYPE_MAX-1);

    p_path_info = ctc_vector_get(p_xdata_master[lchip]->path_vec, SYS_XDATA_ENCODE_PATH_VECTOR_IDX(p_path->type, p_path->prof_id));
    if(!p_path_info)
    {
        return CTC_E_NOT_EXIST;
    }

    p_path->num = p_path_info->num;
    for(loop = 0; loop < p_path_info->num; loop++)
    {
        p_path->map[loop].width = p_path_info->field[loop].width;
        p_path->map[loop].src_offset = p_path_info->field[loop].src_offset;
        p_path->map[loop].dst_offset = p_path_info->field[loop].dst_offset;
    }
    p_path->fixed_bmp = p_path_info->fixed_bmp;

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_xdata_local_check_param(uint8 lchip, ctc_xdata_local_t* p_local)
{
    uint8 loop1 = 0;
    ctc_xdata_map_t* p_field = NULL;
    uint32 xdata_bmp[2][4] = {{0}};       /* src/dst 128bit xdata */
    int32 v_bit[2] = {0};            /* src/dst valid bits */

    CTC_MAX_VALUE_CHECK(p_local->type, CTC_XDATA_LOCAL_TYPE_MAX-1);
    CTC_MAX_VALUE_CHECK(p_local->mode, 2);
    CTC_MAX_VALUE_CHECK(p_local->num, SYS_XDATA_LOCAL_FIELD_MAX);
    if(p_xdata_master[lchip]->local[p_local->type].ref_cnt)
    {
        return CTC_E_IN_USE;
    }

    /* FLOW_HASH_EXT check*/
    if(CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT == p_local->type)
    {
        if(p_local->mode == 0)
        {/* must have CTC_FIELD_KEY_UDF,not support only xdata mode */
            return CTC_E_NOT_SUPPORT;
        }
    }

    if(p_local->mode == 0 || p_local->mode == 1)
    {/* do noting*/
        return CTC_E_NONE;
    }

    /* check field param */
    for (loop1 = 0; loop1 < p_local->num; loop1++)
    {
        p_field = &p_local->fields[loop1];

        switch(p_field->width)
        {
        case CTC_XDATA_WIDTH_4:
            CTC_VALUE_RANGE_CHECK(p_field->src_offset, 112, 124);
            break;
        case CTC_XDATA_WIDTH_8:
            CTC_VALUE_RANGE_CHECK(p_field->src_offset, 64, 120);
            break;
        case CTC_XDATA_WIDTH_16:
            CTC_MAX_VALUE_CHECK(p_field->src_offset, 112);
            break;
        default:
            return CTC_E_INVALID_PARAM;
        }

        if(0 != p_field->dst_offset%p_field->width || 0 != p_field->src_offset%p_field->width)
        {
            return CTC_E_INVALID_PARAM;
        }

        /* check repeated param */
        CTC_BMP_COUNT_RANGE(xdata_bmp[0], v_bit[0], p_field->src_offset, p_field->width);
        CTC_BMP_COUNT_RANGE(xdata_bmp[1], v_bit[1], p_field->dst_offset, p_field->width);
        if(v_bit[0]||v_bit[1])
        {
            return CTC_E_PARAM_CONFLICT;
        }
        CTC_BMP_SET_RANGE(xdata_bmp[0], p_field->src_offset, p_field->width);
        CTC_BMP_SET_RANGE(xdata_bmp[1], p_field->dst_offset, p_field->width);
    }

    return CTC_E_NONE;

}

STATIC int32
_sys_usw_xdata_local_map_ctc2sys(uint8 lchip, ctc_xdata_local_t* p_local, sys_xdata_local_t* p_sys_local)
{
    uint8 loop = 0, loop1 = 0,loop2=0;
    uint32 temp_bmp = 0;
    uint8 cnt = 0;
    uint8 real_width = 0;
    sys_xdata_local_fixed_map_t* p_fixed_map = NULL;
    sys_xdata_kset_t kset;
    ctc_xdata_map_t* p_field = NULL;

    sal_memset(&kset, 0, sizeof(sys_xdata_kset_t));
    p_sys_local->type = p_local->type;
    sal_memset(&p_xdata_master[lchip]->kset[p_local->type], 0, sizeof(sys_xdata_kset_t));

    /* 1. mode 0, only support xdata, do nothing */
    p_fixed_map = p_xdata_master[lchip]->fixed_map[p_local->type];
    if (0 == p_local->mode)
    {
        p_sys_local->mode = p_local->mode;
        CTC_BMP_SET(p_xdata_master[lchip]->kset[p_local->type].w, CTC_FIELD_KEY_XDATA);
        return CTC_E_NONE;
    }

    /* 2. mode 1, support fixed field */
    if (1 == p_local->mode)
    {
        p_sys_local->mode = p_local->mode;
        do
        {
            if(SYS_FIELD_KEY_INVALID != p_fixed_map[loop1].field)
            {
                CTC_BMP_SET(p_xdata_master[lchip]->kset[p_local->type].w, p_fixed_map[loop1].field);
            }
            for (loop2 = 0; loop2 < SYS_XDATA_LOCAL_FIELD_MAX; loop2++)
            {
                if (!CTC_IS_BIT_SET(p_fixed_map[loop1].bmp, loop2) || CTC_IS_BIT_SET(temp_bmp, loop2))
                {
                    continue;
                }
                CTC_BIT_SET(temp_bmp, loop2);
                p_sys_local->field[cnt].width = local_mapping[loop2].width;
                p_sys_local->field[cnt].src_offset = local_mapping[loop2].offset;
                p_sys_local->field[cnt].dst_offset = local_mapping[loop2].offset;

                cnt++;
                p_sys_local->num = cnt;
            }
        }while(!p_fixed_map[loop1++].is_done);
        return CTC_E_NONE;
    }

    /* 3. mode 2, support mix local xdata */
    for (loop = 0; loop < p_local->num; loop ++)
    {
        p_field = &p_local->fields[loop];
        real_width = (p_field->src_offset >= 112) ? CTC_XDATA_WIDTH_4:
                     ((p_field->src_offset >= 64) ? CTC_XDATA_WIDTH_8 : CTC_XDATA_WIDTH_16);
        loop1 = p_field->width/real_width;
        do
        {
            p_sys_local->field[cnt].width = real_width;
            p_sys_local->field[cnt].src_offset = p_field->src_offset + real_width*(loop1-1);
            p_sys_local->field[cnt].dst_offset = p_field->dst_offset + real_width*(loop1-1);
            cnt++;
        }while(--loop1);
        p_sys_local->num = cnt;
    }
    p_sys_local->mode = p_local->mode;
    CTC_BMP_SET(p_xdata_master[lchip]->kset[p_local->type].w, CTC_FIELD_KEY_XDATA);

    return CTC_E_NONE;

}


STATIC int32
_sys_usw_xdata_local_build(uint8 lchip, ctc_xdata_local_t* p_local, sys_xdata_local_t* p_sys_local, void* p_profile)
{
    uint8 loop = 0;
    uint8 src_id = 0;
    uint8 dst_id = 0;
    uint8 step = XAuxProfile_gSrcNibble_1_mode_f - XAuxProfile_gSrcNibble_0_mode_f;
    sys_xdata_local_field_t* p_field = NULL;

    for(loop = 0; loop < p_sys_local->num; loop++)
    {
        p_field = &p_sys_local->field[loop];
        dst_id = p_field->dst_offset/p_field->width;
        switch(p_field->width)
        {
            case CTC_XDATA_WIDTH_4:
                src_id = (p_field->src_offset - 112)/p_field->width;
                SetXAuxProfile(V, gSrcNibble_0_destId_f + src_id*step, p_profile, dst_id);
                SetXAuxProfile(V, gSrcNibble_0_mode_f + src_id*step, p_profile, 1);
            break;

            case CTC_XDATA_WIDTH_8:
                src_id = (p_field->src_offset - 64)/p_field->width;
                SetXAuxProfile(V, gSrcByte_0_destId_f + src_id*step, p_profile, dst_id);
                SetXAuxProfile(V, gSrcByte_0_mode_f + src_id*step, p_profile, 1);
            break;

            case CTC_XDATA_WIDTH_16:
                src_id = p_field->src_offset/p_field->width;
                SetXAuxProfile(V, gSrcWord_0_destId_f + src_id*step, p_profile, dst_id);
                SetXAuxProfile(V, gSrcWord_0_mode_f + src_id*step, p_profile, 1);
            break;
            default:
                break;
        }
    }

    return CTC_E_NONE;

}

STATIC int32
_sys_usw_xdata_local_add_hw(uint8 lchip, ctc_xdata_local_t* p_local, sys_xdata_local_t* p_sys_local, void* p_profile)
{
    uint32 field_id = 0;
    uint32 tbl_id = 0;
    uint32 cmd = 0;
    ds1_t ds;

    switch (p_local->type)
    {
        case CTC_XDATA_LOCAL_TYPE_SCL:
            field_id = IpeUserIdXCtl_xLkpAuxPorfile_f;
            tbl_id = IpeUserIdXCtl_t;
            break;

        case CTC_XDATA_LOCAL_TYPE_EGS_SCL:
            field_id = EgrSclHashXCtl_xAuxProfile_f;
            tbl_id = EgrSclHashXCtl_t;

            break;

        case CTC_XDATA_LOCAL_TYPE_FLOW_HASH:
            field_id = IpeLookupXCtl_xFlowHashLkpAuxProfile_f;
            tbl_id = IpeLookupXCtl_t;

            break;
        case CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT:
            field_id = IpeLookupXCtl_xLookupAuxProfile_f;
            tbl_id = IpeLookupXCtl_t;

            break;
        case CTC_XDATA_LOCAL_TYPE_IPFIX:
            field_id = IpeFwdFlowHashXCtl_auxDataProfile_f;
            tbl_id = IpeFwdFlowHashXCtl_t;

            break;
        case CTC_XDATA_LOCAL_TYPE_EGS_IPFIX:
            field_id = EpeHeaderEditXCtl_flowTracAuxDataProfile_f;
            tbl_id = EpeHeaderEditXCtl_t;

        default:
            break;
    }
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &ds);
    DRV_SET_FIELD_A(lchip, tbl_id, field_id ,&ds, p_profile);
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &ds);

    /* add db */
    sal_memcpy(&p_xdata_master[lchip]->local[p_local->type], p_sys_local, sizeof(sys_xdata_local_t));
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_MASTER, 1);
    return CTC_E_NONE;

}


STATIC int32
sys_usw_xdata_local_build(uint8 lchip, ctc_xdata_local_t* p_local)
{
    sys_xdata_local_t sys_local;
    XAuxProfile_m profile;

    sal_memset(&sys_local, 0, sizeof(sys_xdata_local_t));
    sal_memset(&profile, 0, sizeof(XAuxProfile_m));

    CTC_ERROR_RETURN(_sys_usw_xdata_local_map_ctc2sys(lchip,  p_local, &sys_local));
    CTC_ERROR_RETURN(_sys_usw_xdata_local_build(lchip, p_local, &sys_local, &profile));
    CTC_ERROR_RETURN(_sys_usw_xdata_local_add_hw(lchip, p_local, &sys_local, &profile));

    return CTC_E_NONE;

}


int32
_sys_usw_xdata_set_local(uint8 lchip, ctc_xdata_local_t* p_local)
{
    /* 1. check param */
    CTC_ERROR_RETURN(_sys_usw_xdata_local_check_param(lchip, p_local));

    /* 2. build xdata local */
    CTC_ERROR_RETURN(sys_usw_xdata_local_build(lchip, p_local));

    return CTC_E_NONE;
}

int32
_sys_usw_xdata_get_local(uint8 lchip, ctc_xdata_local_t* p_local)
{
    sys_xdata_local_t* p_db_local = NULL;
    uint8 loop = 0;

    CTC_MAX_VALUE_CHECK(p_local->type, CTC_XDATA_LOCAL_TYPE_MAX-1);

    p_db_local = &p_xdata_master[lchip]->local[p_local->type];
    if(2 != p_db_local->mode )
    {
        p_local->mode = p_db_local->mode;
        p_local->num = 0;
        return CTC_E_NONE;
    }

    for(loop = 0; loop < p_db_local->num; loop++)
    {
        p_local->fields[loop].width = p_db_local->field[loop].width;
        p_local->fields[loop].src_offset = p_db_local->field[loop].src_offset;
        p_local->fields[loop].dst_offset = p_db_local->field[loop].dst_offset;
    }
    p_local->num = p_db_local->num;
    p_local->mode = 2;
    return CTC_E_NONE;
}


/* Nibble3 Nibble2 Nibble1 Nibble0 Byte5 Byte4 Byte3 Byte2 Byte1 Byte0 Word3 Word2 Word1 Word0 */
/* Nibble3 -> 0x2000 */
/* Nibble2 -> 0x1000 */

/* Nibble1 -> 0x0800 */
/* Nibble0 -> 0x0400 */
/* Byte5   -> 0x0200 */
/* Byte4   -> 0x0100 */

/* Byte3   -> 0x0080 */
/* Byte2   -> 0x0040 */
/* Byte1   -> 0x0020 */
/* Byte0   -> 0x0010 */

/* Word3   -> 0x0008 */
/* Word2   -> 0x0004 */
/* Word1   -> 0x0002 */
/* Word0   -> 0x0001 */


int32
sys_usw_xdata_local_kset_init(uint8 lchip)
{
    uint8 num = 0;
    sys_xdata_local_fixed_map_t map[20];

    /* ingress SCL*/
    //SYS_XDATA_ENCODE_LOCAL_MAP(SYS_SCL_FIELD_KEY_EXT_TYPE, CTC_XDATA_LOCAL_TYPE_SCL, 0x400, 0);/* Nibble0 <- ParserResult.extType(3,0) */
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_L4_USER_TYPE, 0x0800, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_L4_TYPE, 0x1000, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_IP_HDR_ERROR,  0x2000, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_L2_TYPE,  0x2000, 0);
    //SYS_XDATA_ENCODE_LOCAL_MAP(ParserResultExtData,  0x00F6);
    //SYS_XDATA_ENCODE_LOCAL_MAP(tunnelAuxData, 0x0101);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_L3_TYPE, 0x0200, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_VLAN_NUM, 0x0200, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_IP_FRAG, 0x0200, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_CVLAN_RANGE, 0x0008, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_SVLAN_RANGE, 0x0008, 1);
    MALLOC_ZERO(MEM_XDATA_MODULE, p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_SCL], num*sizeof(sys_xdata_local_fixed_map_t));
    sal_memcpy(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_SCL],map,num*sizeof(sys_xdata_local_fixed_map_t));

    /* egress scl */
    num = 0;
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_DST_CID, 0x0001, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_PKT_FWD_TYPE, 0x0800, 1);
    //SYS_XDATA_ENCODE_LOCAL_MAP(SYS_SCL_FIELD_KEY_EXT_TYPE, CTC_XDATA_LOCAL_TYPE_EGS_SCL, 0x2000, 1);
    //SYS_XDATA_ENCODE_LOCAL_MAP(logicDestPortGid, CTC_XDATA_LOCAL_TYPE_EGS_SCL, 0x0004);
    //SYS_XDATA_ENCODE_LOCAL_MAP(mplsEvpnDestEsId, CTC_XDATA_LOCAL_TYPE_EGS_SCL, 0x0020);
    //SYS_XDATA_ENCODE_LOCAL_MAP(ParserResultExtData, CTC_XDATA_LOCAL_TYPE_EGS_SCL, 0x400);
    MALLOC_ZERO(MEM_XDATA_MODULE, p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_EGS_SCL], num*sizeof(sys_xdata_local_fixed_map_t));
    sal_memcpy(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_EGS_SCL],map,num*sizeof(sys_xdata_local_fixed_map_t));

    /* ingress ipfix */
    num = 0;
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0001, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0002, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0004, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0008, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_DISCARD, 0x0010, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_IP_TTL,  0x0020, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0040, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0080, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0100, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0200, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0400, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0800, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x1000, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x2000, 1); 

    MALLOC_ZERO(MEM_XDATA_MODULE, p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_IPFIX], num*sizeof(sys_xdata_local_fixed_map_t));
    sal_memcpy(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_IPFIX],map,num*sizeof(sys_xdata_local_fixed_map_t));

    /* egress ipfix */
    num = 0;
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0001, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0002, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0004, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_SRC_GPORT, 0x0008, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_DISCARD, 0x0010, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_IP_TTL, 0x0020, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0040, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0080, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0100, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0200, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0400, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x0800, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_PRIORITY, 0x1000, 0); 
    SYS_XDATA_ENCODE_LOCAL_MAP(SYS_FIELD_KEY_INVALID, 0x2000, 1); 

    MALLOC_ZERO(MEM_XDATA_MODULE, p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_EGS_IPFIX], num*sizeof(sys_xdata_local_fixed_map_t));
    sal_memcpy(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_EGS_IPFIX],map,num*sizeof(sys_xdata_local_fixed_map_t));

    /* flow hash */
    num = 0;

    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_VLAN_NUM, 0x2000, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_IP_FRAG, 0x2000, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_L4_USER_TYPE, 0x1000, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_L4_TYPE, 0x0800, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_L3_TYPE, 0x0400, 0);

    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_SVLAN_ID, 0x0280, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_CVLAN_ID, 0x0300, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_L2_TYPE, 0x0040, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_STP_STATE, 0x0040, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_CTAG_VALID, 0x0040, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_STAG_VALID, 0x0040, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_DISCARD, 0x0020, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_IP_HDR_ERROR, 0x0020, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_DECAP, 0x0010, 0);

    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_VRFID, 0x0008, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_FID, 0x0004, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_LOGIC_SRC_PORT, 0x0002, 0);
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_INTERFACE_ID, 0x0001, 1);

    MALLOC_ZERO(MEM_XDATA_MODULE, p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_FLOW_HASH], num*sizeof(sys_xdata_local_fixed_map_t));
    sal_memcpy(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_FLOW_HASH],map,num*sizeof(sys_xdata_local_fixed_map_t));

    /* flow hash ext*/
    num = 0;
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0x3c00, 0);/* 8bit valid 8bit hit idx */
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0x0001, 0);/* udf0 */
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0x0002, 0);/* udf1 */
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0x0004, 0);/* udf2 */
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0x0008, 0);/* udf3 */
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0x0030, 0);/* udf4 */
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0x00c0, 0);/* udf5 */
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0x0100, 0);/* udf6 */
    SYS_XDATA_ENCODE_LOCAL_MAP(CTC_FIELD_KEY_UDF, 0x0200, 1);/* udf7 */


    MALLOC_ZERO(MEM_XDATA_MODULE, p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT], num*sizeof(sys_xdata_local_fixed_map_t));
    sal_memcpy(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT],map,num*sizeof(sys_xdata_local_fixed_map_t));

    return CTC_E_NONE;
}

int32
sys_usw_xdata_local_kset_deint(uint8 lchip)
{

    mem_free(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_SCL]);
    mem_free(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_EGS_SCL]);
    mem_free(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_IPFIX]);
    mem_free(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_EGS_IPFIX]);
    mem_free(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_FLOW_HASH]);
    mem_free(p_xdata_master[lchip]->fixed_map[CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT]);

    return CTC_E_NONE;
}

/****************************************************************************
*
* local xdata -> flex key
*
*****************************************************************************/

STATIC int32
_sys_usw_xdata_get_hash_info(uint8 lchip, uint32 tbl_id, uint8* hash_type)
{
    switch(tbl_id)
    {
/*SCL*/
    case DsUserIdDoubleVlanPortHashKey_t:
    case DsUserId1DoubleVlanPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_DOUBLEVLANPORT);
        break;

    case DsUserIdSvlanPortHashKey_t:
    case DsUserId1SvlanPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_SVLANPORT);
        break;

    case DsUserIdNshHashKey_t:
    case DsUserId1NshHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_NSH);
        break;

    case DsUserIdCvlanPortHashKey_t:
    case DsUserId1CvlanPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_CVLANPORT);
        break;

    case DsUserIdSvlanCosPortHashKey_t:
    case DsUserId1SvlanCosPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_SVLANCOSPORT);
        break;

    case DsUserIdCvlanCosPortHashKey_t:
    case DsUserId1CvlanCosPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_CVLANCOSPORT);
        break;

    case DsUserIdMacPortHashKey_t:
    case DsUserId1MacPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_MACPORT);
        break;

    case DsUserIdIpv4PortHashKey_t:
    case DsUserId1Ipv4PortHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_IPV4PORT);
        break;

    case DsUserIdMacHashKey_t:
    case DsUserId1MacHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_MAC);
        break;

    case DsUserIdIpv4SaHashKey_t:
    case DsUserId1Ipv4SaHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_IPV4SA);
        break;

    case DsUserIdPortHashKey_t:
    case DsUserId1PortHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_PORT);
        break;

    case DsUserIdSvlanMacSaHashKey_t:
    case DsUserId1SvlanMacSaHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_SVLANMACSA);
        break;

    case DsUserIdSvlanHashKey_t:
    case DsUserId1SvlanHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_SVLAN);
        break;

    case DsUserIdEcidNameSpaceHashKey_t:
    case DsUserId1EcidNameSpaceHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_ECIDNAMESPACE);
        break;

    case DsUserIdIngEcidNameSpaceHashKey_t:
    case DsUserId1IngEcidNameSpaceHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_INGECIDNAMESPACE);
        break;

    case DsUserIdIpv6SaHashKey_t:
    case DsUserId1Ipv6SaHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_IPV6SA);
        break;

    case DsUserIdIpv6PortHashKey_t:
    case DsUserId1Ipv6PortHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_IPV6PORT);
        break;

    case DsUserIdIpv4DaHashKey_t:
    case DsUserId1Ipv4DaHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_IPV4DA);
        break;

    case DsUserIdIpv6DaHashKey_t:
    case DsUserId1Ipv6DaHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_IPV6DA);
        break;

    case DsUserId0VlanPortDscpHashKey_t:
    case DsUserId1VlanPortDscpHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_VLANDSCPPORT);
        break;

    case DsUserIdTunnelIpv4HashKey_t:
    case DsUserId1TunnelIpv4HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4);
        break;
#if 0
    case DsUserIdTunnelIpv4GreKeyHashKey_t:
    case DsUserId1TunnelIpv4GreKeyHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4GREKEY);
        break;
    case DsUserIdTunnelIpv4UdpHashKey_t:
    case DsUserId1TunnelIpv4UdpHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4UDP);
        break;
    case DsUserIdTunnelTrillMcAdjHashKey_t:
    case DsUserId1TunnelTrillMcAdjHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELTRILLMCADJ);
        break;
    case DsUserIdTunnelTrillMcDecapHashKey_t:
    case DsUserId1TunnelTrillMcDecapHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELTRILLMCDECAP);
        break;
    case DsUserIdTunnelTrillMcRpfHashKey_t:
    case DsUserId1TunnelTrillMcRpfHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELTRILLMCRPF);
        break;
    case DsUserIdTunnelTrillUcDecapHashKey_t:
    case DsUserId1TunnelTrillUcDecapHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELTRILLUCDECAP);
        break;
    case DsUserIdTunnelTrillUcRpfHashKey_t:
    case DsUserId1TunnelTrillUcRpfHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELTRILLUCRPF);
        break;
    case DsUserIdTunnelIpv4RpfHashKey_t:
    case DsUserId1TunnelIpv4RpfHashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4RPF);
        break;
    case DsUserIdTunnelIpv4UcVxlanMode0HashKey_t:
    case DsUserId1TunnelIpv4UcVxlanMode0HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4UCVXLANMODE0);
        break;
    case DsUserIdTunnelIpv4UcVxlanMode1HashKey_t:
    case DsUserId1TunnelIpv4UcVxlanMode1HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4UCVXLANMODE1);
        break;
    case DsUserIdTunnelIpv6UcVxlanMode0HashKey_t:
    case DsUserId1TunnelIpv6UcVxlanMode0HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV6UCVXLANMODE0);
        break;

    case DsUserIdTunnelIpv6UcVxlanMode1HashKey_t:
    case DsUserId1TunnelIpv6UcVxlanMode1HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV6UCVXLANMODE1);
        break;
    case DsUserIdTunnelIpv4UcNvgreMode0HashKey_t:
    case DsUserId1TunnelIpv4UcNvgreMode0HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4UCNVGREMODE0);
        break;
    case DsUserIdTunnelIpv4UcNvgreMode1HashKey_t:
    case DsUserId1TunnelIpv4UcNvgreMode1HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4UCNVGREMODE1);
        break;
    case DsUserIdTunnelIpv6UcNvgreMode0HashKey_t:
    case DsUserId1TunnelIpv6UcNvgreMode0HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV6UCNVGREMODE0);
        break;
    case DsUserIdTunnelIpv6UcNvgreMode1HashKey_t:
    case DsUserId1TunnelIpv6UcNvgreMode1HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV6UCNVGREMODE1);
        break;
    case DsUserIdTunnelIpv4McNvgreMode0HashKey_t:
    case DsUserId1TunnelIpv4McNvgreMode0HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4MCNVGREMODE0);
        break;
    case DsUserIdTunnelIpv4McVxlanMode0HashKey_t:
    case DsUserId1TunnelIpv4McVxlanMode0HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4MCVXLANMODE0);
        break;
    case DsUserIdTunnelIpv4VxlanMode1HashKey_t:
    case DsUserId1TunnelIpv4VxlanMode1HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4VXLANMODE1);
        break;
    case DsUserIdTunnelIpv6McVxlanMode0HashKey_t:
    case DsUserId1TunnelIpv6McVxlanMode0HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV6MCVXLANMODE0);
        break;
    case DsUserIdTunnelIpv6McVxlanMode1HashKey_t:
    case DsUserId1TunnelIpv6McVxlanMode1HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV6MCVXLANMODE1);
        break;
    case DsUserIdTunnelIpv6McNvgreMode0HashKey_t:
    case DsUserId1TunnelIpv6McNvgreMode0HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV6MCNVGREMODE0);
        break;
    case DsUserIdTunnelIpv6McNvgreMode1HashKey_t:
    case DsUserId1TunnelIpv6McNvgreMode1HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV6MCNVGREMODE1);
        break;

    case DsUserIdTunnelIpv4NvgreMode1HashKey_t:
    case DsUserId1TunnelIpv4NvgreMode1HashKey_t:
        *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_TUNNELIPV4NVGREMODE1);
        break;
#endif
    case DsUserIdSclFlowL2HashKey_t:
    case DsUserId1SclFlowL2HashKey_t:
    *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_SCLFLOWL2);
    break;

    case DsUserIdSclFlowL2UDFHashKey_t:
    case DsUserId1SclFlowL2UDFHashKey_t:
    *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_SCLFLOWL2UDF);
    break;

    case DsUserIdSclFlowL3UDFHashKey_t:
    case DsUserId1SclFlowL3UDFHashKey_t:
    *hash_type = DRV_ENUM(DRV_USERIDHASHTYPE_SCLFLOWL3UDF);
    break;

/*
    case DsUserIdSclFlowPktL2HashKey_t:
    case DsUserId1SclFlowPktL2HashKey_t:
    *hash_type = ;
    break;

    case DsUserIdSclFlowPktL3HashKey_t:
    case DsUserId1SclFlowPktL3HashKey_t:
    *hash_type = ;
    break;

    case DsUserIdNshHashKey_t:
    case DsUserId1NshHashKey_t:
    *hash_type = ;
    break;
*/

/*Flow hash*/
    case DsFlowL2HashKey_t:
        *hash_type = DRV_ENUM(DRV_FLOWHASHTYPE_L2);
        break;
    case DsFlowL2L3HashKey_t:
        *hash_type = DRV_ENUM(DRV_FLOWHASHTYPE_L2L3);
        break;
    case DsFlowL3Ipv4HashKey_t:
        *hash_type = DRV_ENUM(DRV_FLOWHASHTYPE_L3IPV4);
        break;
    case DsFlowL3Ipv6HashKey_t:
        *hash_type = DRV_ENUM(DRV_FLOWHASHTYPE_L3IPV6);
        break;
    case DsFlowL3MplsHashKey_t:
        *hash_type = DRV_ENUM(DRV_FLOWHASHTYPE_L3MPLS);
        break;

/*Ipfix hash*/
    case DsIpfixL2HashKey0_t:
    case DsIpfixL2HashKey1_t:
        *hash_type = DRV_ENUM(DRV_IPFIXHASHTYPE_L2);
        break;
    case DsIpfixL2L3HashKey0_t:
    case DsIpfixL2L3HashKey1_t:
        *hash_type = DRV_ENUM(DRV_IPFIXHASHTYPE_L2L3);
        break;
    case DsIpfixL3Ipv4HashKey0_t:
    case DsIpfixL3Ipv4HashKey1_t:
        *hash_type = DRV_ENUM(DRV_IPFIXHASHTYPE_L3IPV4);
        break;
    case DsIpfixL3Ipv6HashKey0_t:
    case DsIpfixL3Ipv6HashKey1_t:
        *hash_type = DRV_ENUM(DRV_IPFIXHASHTYPE_L3IPV6);
        break;
    case DsIpfixL3MplsHashKey0_t:
    case DsIpfixL3MplsHashKey1_t:
        *hash_type = DRV_ENUM(DRV_IPFIXHASHTYPE_L3MPLS);
        break;
    case DsIpfixL3Ipv4ShortHashKey0_t:
    case DsIpfixL3Ipv4ShortHashKey1_t:
        *hash_type = DRV_ENUM(DRV_IPFIXHASHTYPE_L3IPV4SHORT);
        break;
    case DsIpfixL3Ipv6ShortHashKey0_t:
    case DsIpfixL3Ipv6ShortHashKey1_t:
        *hash_type = DRV_ENUM(DRV_IPFIXHASHTYPE_L3IPV6SHORT);
        break;
    case DsIpfixUdfShortHashKey0_t:
    case DsIpfixUdfShortHashKey1_t:
         *hash_type = DRV_ENUM(DRV_IPFIXHASHTYPE_UDFSHORT);
         break;
    case DsIpfixUdfHashKey0_t:
    case DsIpfixUdfHashKey1_t:
         *hash_type = DRV_ENUM(DRV_IPFIXHASHTYPE_UDF);
         break;

 /*egress scl*/
    case DsEgressScl0DoubleVlanPortHashKey_t:
    case DsEgressScl1DoubleVlanPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSXCOAMHASHTYPE_DOUBLEVLANPORT);
        break;
    case DsEgressScl0SvlanPortHashKey_t:
    case DsEgressScl1SvlanPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSXCOAMHASHTYPE_SVLANPORT);
        break;
    case DsEgressScl0CvlanPortHashKey_t:
    case DsEgressScl1CvlanPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSXCOAMHASHTYPE_CVLANPORT);
        break;
    case DsEgressScl0SvlanCosPortHashKey_t:
    case DsEgressScl1SvlanCosPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSXCOAMHASHTYPE_SVLANCOSPORT);
        break;
    case DsEgressScl0CvlanCosPortHashKey_t:
    case DsEgressScl1CvlanCosPortHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSXCOAMHASHTYPE_CVLANCOSPORT);
        break;
    case DsEgressScl0PortVlanCrossHashKey_t:
    case DsEgressScl1PortVlanCrossHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSXCOAMHASHTYPE_PORTVLANCROSS);
        break;
    case DsEgressScl0PortCrossHashKey_t:
    case DsEgressScl1PortCrossHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSXCOAMHASHTYPE_PORTCROSS);
        break;
    case DsEgressScl0PortHashKey_t:
    case DsEgressScl1PortHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSXCOAMHASHTYPE_PORT);
        break;
    case DsEgressScl0SvlanPortMacHashKey_t:
    case DsEgressScl1SvlanPortMacHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSXCOAMHASHTYPE_SVLANPORTMAC);
        break;
    case DsEgressScl0FidDvpGroupHashKey_t:
    case DsEgressScl1FidDvpGroupHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSSCLHASHTYPE_FIDDVPGROUP);
        break;
    case DsEgressScl0MetadataDvpGroupHashKey_t:
    case DsEgressScl1MetadataDvpGroupHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSSCLHASHTYPE_METADATADVPGROUP);
        break;
    case DsEgressScl0VpPairHashKey_t:
    case DsEgressScl1VpPairHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSSCLHASHTYPE_VPPAIR);
        break;
    case DsEgressScl0I2eCidDvpGroupHashKey_t:
    case DsEgressScl1I2eCidDvpGroupHashKey_t:
        *hash_type = DRV_ENUM(DRV_EGRESSSCLHASHTYPE_I2ECIDDVPGROUP);
        break;
    case DsEgressScl0MetadataDvpHashKey_t:
    case DsEgressScl1MetadataDvpHashKey_t:
        *hash_type = 0xF;
        break;

     default:
        return -1;
    }

    return 0;
}


STATIC int32
_sys_usw_xdata_get_tcam_info(uint8 lchip, uint32 tbl_id, uint8* tcam_type)
{
    switch(tbl_id)
    {
    case DsScl0MacKey160_t:
    case DsScl2MacKey160_t:
    case DsScl1MacKey160_t:
    case DsScl3MacKey160_t:
        *tcam_type = DRV_ENUM(DRV_SCL_KEY_TYPE_MACKEY160);
        break;
    case DsScl0L3Key160_t:
    case DsScl2L3Key160_t:
    case DsScl1L3Key160_t:
    case DsScl3L3Key160_t:
        *tcam_type = DRV_ENUM(DRV_SCL_KEY_TYPE_L3KEY160);
        break;
    case DsScl0Ipv6Key320_t:
    case DsScl2Ipv6Key320_t:
    case DsScl1Ipv6Key320_t:
    case DsScl3Ipv6Key320_t:
        *tcam_type = DRV_ENUM(DRV_SCL_KEY_TYPE_IPV6KEY320);
        break;
    case DsScl0MacL3Key320_t:
    case DsScl2MacL3Key320_t:
    case DsScl1MacL3Key320_t:
    case DsScl3MacL3Key320_t:
        *tcam_type = DRV_ENUM(DRV_SCL_KEY_TYPE_MACL3KEY320);
        break;
    case DsScl0MacIpv6Key640_t:
    case DsScl2MacIpv6Key640_t:
    case DsScl1MacIpv6Key640_t:
    case DsScl3MacIpv6Key640_t:
        *tcam_type = DRV_ENUM(DRV_SCL_KEY_TYPE_MACIPV6KEY640);
        break;
    case DsScl0UdfKey160_t:
    case DsScl2UdfKey160_t:
    case DsScl1UdfKey160_t:
    case DsScl3UdfKey160_t:
        *tcam_type = DRV_ENUM(DRV_SCL_KEY_TYPE_UDFKEY160);
        break;
    case DsScl0UdfKey320_t:
    case DsScl2UdfKey320_t:
    case DsScl1UdfKey320_t:
    case DsScl3UdfKey320_t:
        *tcam_type = DRV_ENUM(DRV_SCL_KEY_TYPE_UDFKEY320);
        break;
    case DsScl0UdfKey640_t:
    case DsScl1UdfKey640_t:
        *tcam_type = DRV_ENUM(DRV_SCL_KEY_TYPE_UDFKEY640);
        break;
    /*
    case DsScl0ExtTypeDataKey160_t:
    case DsScl0PktL2Key320_t:
    case DsScl0PktL3L4Key640_t:
    case DsSclExtTypeDataKey160_t:
    */
    default:
        break;
    }
    return 0;
}


STATIC int32
_sys_usw_xdata_fk_field_cmp(sys_xdata_fk_f_db_t* val1, sys_xdata_fk_f_db_t* val2)
{
    if(val1->width < val2->width)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

STATIC int32
_sys_usw_xdata_fk_field_del(sys_xdata_fk_f_db_t* node)
{
    if (NULL != node)
    {
        mem_free(node);
    }
    return 0;
}

STATIC int32
_sys_usw_xdata_get_fk_f_info(uint8 lchip, ctc_xdata_local_type_t type,sys_xdata_fk_field_t* fk_field, sys_xdata_fk_f_info_t* f_info)
{
    uint8 loop = 0;
    uint8 base[5] = {0,112,64,0,0};
    uint8 offset = 0;
    sys_xdata_local_t* p_local= NULL;
    sys_xdata_fk_f_info_t* p_f_info = NULL;

    if(type != CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT && SYS_FK_F_UDF_VALID <= fk_field->field && SYS_FK_F_UDF_DATA7 >= fk_field->field)
    {
        return CTC_E_NONE;
    }
    p_f_info = &p_xdata_master[lchip]->fk_f_info[type][fk_field->field];
    p_local = &p_xdata_master[lchip]->local[type];

    if(SYS_FK_F_XDATA == fk_field->field)
    {
        /*
        bit_offset = (1 << (fk_field->width/CTC_XDATA_WIDTH_4))-1;

        if (0 != (p_local->used_bmp & (bit_offset << fk_field->src_pos)))
        {
            return CTC_E_PARAM_CONFLICT;
        }
        */
        f_info->width = fk_field->width;
        f_info->bit_width = fk_field->width;
        f_info->src_pos = fk_field->src_pos;
        return CTC_E_NONE;
    }


    sal_memcpy(f_info,p_f_info,sizeof(sys_xdata_fk_f_info_t));
    for (loop = 0; loop < p_local->num;loop++)
    {
        offset = p_f_info->src_pos*p_f_info->width + base[p_f_info->width/CTC_XDATA_WIDTH_4];
        if(p_local->field[loop].width != p_f_info->width ||
            p_local->field[loop].src_offset != offset)
        {
            continue;
        }
        f_info->src_pos = p_local->field[loop].dst_offset/CTC_XDATA_WIDTH_4;
        break;
    }

    if(SYS_XDATA_LOCAL_FIELD_MAX == loop)
    {
        return CTC_E_ENTRY_NOT_EXIST;
    }
    return CTC_E_NONE;
}


STATIC void*
_sys_usw_xdata_lkup_fk_field(uint8 lchip, ctc_linklist_t* pf_db, sys_xdata_fk_f_info_t* pf_info, sys_xdata_fk_field_t* fk_field)
{
    ctc_listnode_t*   node = NULL;
    sys_xdata_fk_f_db_t *pf_db_node = NULL;

    CTC_LIST_LOOP(pf_db, pf_db_node, node)
    {
        if (pf_db_node->field == fk_field->field &&
            pf_db_node->pos_sel == pf_info->src_pos &&
            pf_db_node->width == pf_info->width)
        {
            return pf_db_node;
        }
    }
    return NULL;
}


STATIC int32
_sys_usw_xdata_add_fk_field(uint8 lchip,sys_xdata_fk_t* p_fk, sys_xdata_fk_f_db_t **ppf_db, sys_xdata_fk_db_t* p_fk_node)
{
    sys_xdata_fk_field_t* fk_field = &p_fk->info;
    sys_xdata_fk_f_info_t f_info;
    sys_xdata_fk_f_db_t* old_pf_db = NULL;
    sys_xdata_fk_f_db_t* pf_db = NULL;

    sal_memset(&f_info, 0, sizeof(sys_xdata_fk_f_info_t));

    CTC_ERROR_RETURN(_sys_usw_xdata_get_fk_f_info(lchip, p_fk->type, fk_field, &f_info));

    old_pf_db = _sys_usw_xdata_lkup_fk_field(lchip, p_fk_node->field_list, &f_info, fk_field);
    if (old_pf_db)
    {
        return CTC_E_PARAM_CONFLICT;
    }

    pf_db = mem_malloc(MEM_XDATA_MODULE, sizeof(sys_xdata_fk_f_db_t));
    if (!pf_db)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(pf_db, 0, sizeof(sys_xdata_fk_f_db_t));
    pf_db->field = fk_field->field;
    pf_db->width = f_info.width;
    pf_db->pos_sel = f_info.src_pos;
    pf_db->bit_width = f_info.bit_width;
    pf_db->start_bit = f_info.offset;
    pf_db->mask = 0xffff;/* default mask is 0xffff */
    if(SYS_FK_F_XDATA == p_fk->info.field)
    {
        pf_db->mask = fk_field->mask ? fk_field->mask : 0xffff;
    }
    pf_db->father_field = f_info.share_field;
    pf_db->ptr_field_name = fk_field->ptr_field_name;

    if(CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT == p_fk->type && SYS_FK_F_UDF_HIT_INDEX == fk_field->field)
    {/* get flow hash ext hash type position */
        p_fk_node->type_sel = f_info.src_pos;
    }

    if (SYS_FK_F_UDF_VALID <= fk_field->field && SYS_FK_F_UDF_DATA7 >= fk_field->field)
    {
        p_fk_node->udf_en = 1;
        if(SYS_FK_F_UDF_DATA0 <= fk_field->field && SYS_FK_F_UDF_DATA7 >= fk_field->field)
        {
            CTC_BIT_SET(p_fk_node->udf_bmp, ((fk_field->field - SYS_FK_F_UDF_DATA0)/2));
        }
    }
    (*ppf_db) = pf_db;
    return CTC_E_NONE;
}

enum sys_fk_udf_e
{
    SYS_FK_UDF_HIT_INDEX,
    SYS_FK_UDF_DATA0,
    SYS_FK_UDF_DATA1,
    SYS_FK_UDF_DATA2,
    SYS_FK_UDF_DATA3,
    SYS_FK_UDF_DATA4,
    SYS_FK_UDF_DATA5,
    SYS_FK_UDF_DATA6,
    SYS_FK_UDF_DATA7,
    SYS_FK_UDF_NUM
};

#define SYS_FK_SEL_NONE               0
#define SYS_FK_SEL_NIBBLE             1
#define SYS_FK_SEL_BYTE               2
#define SYS_FK_SEL_WORD               3
#define SYS_FK_SEL_DWORD              4
#define SYS_FK_SEL_QWORD              5
#define SYS_FK_SEL_WORD_QWORD         6
#define SYS_FK_SEL_NIBBLE_BYTE_QWORD  7
#define SYS_FK_SEL_QWORD_QWORD        8   /*not support*/
#define SYS_FK_SEL_NIBBLE_WORD        9
#define SYS_FK_SEL_BYTE_DWORD         10
#define SYS_FK_SEL_WORD_DWORD         11
#define SYS_FK_SEL_QWORD_LOW          12
#define SYS_FK_SEL_XAUXDATA           13
#define SYS_FK_SEL_UDF_16BIT          14
#define SYS_FK_SEL_UDF_32BIT          15
#define SYS_FK_SEL_UDF_64BIT          16
#define SYS_FK_SEL_UDF_128BIT         17
#define SYS_FK_SEL_DIRECT_AD          18
#define SYS_FK_SEL_ALL                255


#define SYS_FK_GEN_L0_PROF_NUM    2


#define SYS_XDATA_FK_NORMAL_FIELD    0
#define SYS_XDATA_FK_STD_FIELD_SET   1
#define SYS_XDATA_FK_STD_FIELD_UNSET 2
#define SYS_SYS_XDATA_FK_IS_STD_FIELD(field)  ((field) >= SYS_FK_F_XDATA_NIBBLE0 && (field) <= SYS_FK_F_XDATA_WORD3)

/*replace the empty position*/
#define SYS_FK_MODE_REPLACE1      0
/*expand the key type*/
#define SYS_FK_MODE_APPEND        1
/*replace the whole key*/
#define SYS_FK_MODE_REPLACE2      2

#define SYS_FK_SIZE_SINGLE   0
#define SYS_FK_SIZE_DOUBLE   1
#define SYS_FK_SIZE_QUAD     2

const _sys_xdata_fk_info_t*
sys_usw_xdata_get_fk_info(uint8 lchip, sys_xdata_fk_db_t* p_fk_node)
{
    const _sys_xdata_fk_info_t* p_fk_info[3] = {NULL, NULL, NULL};
    uint8 key_size_multi = 2;
    uint8 key_size = 0;

    #define _SYS_FK_GET_KEY_SIZE(table_base)  (\
        DRV_TABLE_ENTRY_SIZE(lchip, p_fk_node->tbl_id) / DRV_TABLE_ENTRY_SIZE(lchip, table_base)\
        )

    switch(p_fk_node->type)
    {
    case CTC_XDATA_LOCAL_TYPE_SCL:
        if (p_fk_node->hash_type == 0xFF)
        {
            p_fk_info[0] = &i_scl_fk_info[0][0];
            p_fk_info[1] = &i_scl_fk_info[1][0];
            p_fk_info[2] = &i_scl_fk_info[2][0];
        }
        else
        {
            p_fk_info[0] = &userid_fk_info[0][0];
            p_fk_info[1] = &userid_fk_info[1][0];
            p_fk_info[2] = &userid_fk_info[2][0];
        }
        break;

    case CTC_XDATA_LOCAL_TYPE_FLOW_HASH:
        p_fk_info[0] = &flow_fk_info[0][0];
        p_fk_info[1] = &flow_fk_info[1][0];
        p_fk_info[2] = &flow_fk_info[2][0];
        key_size_multi = 1;
        break;
    case CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT:
        p_fk_info[0] = &flow_ext_fk_info[0][0];
        p_fk_info[1] = &flow_ext_fk_info[1][0];
        p_fk_info[2] = &flow_ext_fk_info[2][0];
        break;

    case CTC_XDATA_LOCAL_TYPE_IPFIX:
    case CTC_XDATA_LOCAL_TYPE_EGS_IPFIX:
        p_fk_info[0] = &ipfix_fk_info[0][0];
        p_fk_info[1] = &ipfix_fk_info[1][0];
        p_fk_info[2] = &ipfix_fk_info[2][0];
        break;

    case CTC_XDATA_LOCAL_TYPE_EGS_SCL:
        p_fk_info[0] = &e_scl_fk_info[0][0];
        p_fk_info[1] = &e_scl_fk_info[1][0];
        p_fk_info[2] = &e_scl_fk_info[2][0];
        key_size_multi = 4;
        break;

    default:
        break;
    }

    if (!p_fk_info[0] || !p_fk_info[1] || !p_fk_info[2])
    {
        return NULL;
    }
    key_size = _SYS_FK_GET_KEY_SIZE(p_fk_info[0][0].tbl_id) * 2 / key_size_multi;
    switch(key_size)
    {
    case 1:
        p_fk_node->key_size = SYS_FK_SIZE_SINGLE;
        break;
    case 2:
        p_fk_node->key_size = SYS_FK_SIZE_DOUBLE;
        break;
    case 4:
        p_fk_node->key_size = SYS_FK_SIZE_QUAD;
        break;
    default:
        break;
    }
    return (p_fk_info[p_fk_node->mode] + p_fk_node->key_size);
}


/*get reserved field offset of flex key*/
STATIC int32
_sys_usw_xdata_get_fk_field_offset(uint8 lchip, sys_xdata_fk_db_t* p_fk_node, uint16* offset, uint16* udf_offset, uint16* min_offset, uint8 width)
{
    fields_t* p_field = NULL;
    const _sys_xdata_fk_info_t* p_fk_info = NULL;
    uint32 entry_num = 0;
    uint8 step = 0;

    p_fk_info = sys_usw_xdata_get_fk_info(lchip, p_fk_node);
    if (!p_fk_info)
    {
        return CTC_E_NONE;
    }
    drv_get_table_property(lchip, DRV_TABLE_PROP_FIELD_INFO, p_fk_info->tbl_id,
                           p_fk_info->fld_id, &p_field);
    sys_usw_ftm_query_table_entry_num(lchip, p_fk_node->tbl_id, &entry_num);
    if (!p_field || width > p_field->bits || !entry_num)
    {
        return CTC_E_NO_RESOURCE;
    }
#ifdef AT_DROP
    if (1 == p_fk_info->append)
    {
        (*offset) = 0;
        (*udf_offset) = p_field->bits;
    }
    else
    {
        (*offset) = p_field->bits - width;
        (*udf_offset) = (*offset);
        (*min_offset) = drv_get_key_width(lchip, p_fk_node->tbl_id);
        if ((*offset) < (*min_offset))
        {
            return CTC_E_NO_RESOURCE;
        }
    }
#else
    if(p_fk_node->is_direct_key)
    {
        (*offset) = 0;
        (*udf_offset) = 0;
    }
    else if (1 == p_fk_info->append)
    {
        (*offset) = 0;
        (*udf_offset) = p_field->bits;
    /*
        (*offset) = (p_field->ptr_seg[p_field->seg_num-1].word_offset << 5) +
                     p_field->ptr_seg[p_field->seg_num-1].start;
        (*udf_offset) = (p_field->ptr_seg[0].word_offset << 5) + p_field->ptr_seg[0].start + p_field->ptr_seg[0].bits;
        */
    }
    else
    {
        (*offset) = (p_field->ptr_seg[0].word_offset << 5) + p_field->ptr_seg[0].start +
                     p_field->ptr_seg[0].bits - width;
        (*min_offset) = drv_get_table_max_band(lchip, p_fk_node->tbl_id);
        if (!p_fk_info->append && (*offset) < (*min_offset))
        {
            return CTC_E_NO_RESOURCE;
        }
        if(1 != p_fk_info->append && p_fk_node->key_size == SYS_FK_SIZE_SINGLE &&
            (CTC_XDATA_LOCAL_TYPE_IPFIX == p_fk_node->type || CTC_XDATA_LOCAL_TYPE_EGS_IPFIX == p_fk_node->type))
        {
            step = 1;
        }
        (*min_offset) = !p_fk_info->append ? (p_field->bits - ((*offset) - (*min_offset) + width)) : 0;
        (*offset) = p_field->bits - width - step;
        (*udf_offset) = (*offset);
    }
#endif

    return CTC_E_NONE;
}


/*
udf_bitmap: 0----------1------2------3------4------5------6------7------8----
            hit_index--data0--data1--data2--data3--data4--data5--data6--data7
*/
STATIC uint8
_sys_usw_xdata_get_scl_presel(uint8 lchip, sys_xdata_fk_db_t* p_fk_node, uint16 udf_bitmap, uint32 bit_vector)
{
    uint8  key_gen_presel = 0;
    if (p_fk_node->mode == SYS_FK_MODE_REPLACE1 || p_fk_node->mode == SYS_FK_MODE_REPLACE2)
    {
        switch(p_fk_node->key_size)
        {
        case SYS_FK_SIZE_SINGLE:
            SYS_XDATA_MAX_VALUE_CHECK(udf_bitmap, 0xF, SYS_FK_SEL_NONE);
            if (CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA2))
            {
                key_gen_presel = SYS_FK_SEL_BYTE;
            }
            else if (CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA1))
            {
                key_gen_presel = SYS_FK_SEL_WORD;
            }
            else    /*CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA0)*/
            {
                key_gen_presel = SYS_FK_SEL_DWORD;
            }
            break;
        case SYS_FK_SIZE_DOUBLE:
            SYS_XDATA_MAX_VALUE_CHECK(udf_bitmap, 0xFF, SYS_FK_SEL_NONE);
            if (CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA6))
            {
                key_gen_presel = SYS_FK_SEL_WORD;
            }
            else if (CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA5) || CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA4))
            {
                key_gen_presel = SYS_FK_SEL_DWORD;
            }
            else    /*CTC_IS_BIT_SET(udf_bitmap, SYS_FK_F_UDF_DATA3)*/
            {
                key_gen_presel = SYS_FK_SEL_QWORD;
            }
            break;
        case SYS_FK_SIZE_QUAD:
            key_gen_presel = SYS_FK_SEL_ALL;
            break;
        default:
            return SYS_FK_SEL_NONE;
        }

    }
    else    /*append*/
    {
        switch(p_fk_node->key_size)
        {
        case SYS_FK_SIZE_SINGLE:
            SYS_XDATA_MAX_VALUE_CHECK(udf_bitmap, 0x1F, SYS_FK_SEL_NONE);
            if (CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA3))
            {
                key_gen_presel = SYS_FK_SEL_BYTE;
            }
            else if (CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA2))
            {
                key_gen_presel = SYS_FK_SEL_WORD;
            }
            else if (CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA1) || CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA0))
            {
                key_gen_presel = SYS_FK_SEL_DWORD;
            }
            else    /*CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_HIT_INDEX)*/
            {
                key_gen_presel = SYS_FK_SEL_QWORD;
            }
            break;
        case SYS_FK_SIZE_DOUBLE:
            if (CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA7))
            {
                key_gen_presel = SYS_FK_SEL_WORD;
            }
            else if (CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA6) || CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA5))
            {
                key_gen_presel = SYS_FK_SEL_DWORD;
            }
            else if (CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA4) || CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA3)
                   || CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA2) || CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA1))
            {
                key_gen_presel = SYS_FK_SEL_QWORD;
            }
            else    /*CTC_IS_BIT_SET(udf_bitmap, SYS_FK_UDF_DATA0)*/
            {
                key_gen_presel = SYS_FK_SEL_ALL;
            }
            break;
        default:
            return SYS_FK_SEL_NONE;
        }
    }
    return key_gen_presel;
}


STATIC int8
_sys_usw_xdata_get_fk_sel(uint8 lchip, uint8 node, uint8 fk_sel)
{
    if (SYS_XDATA_LOCAL_TYPE_XHASH == node)
    {
        switch(fk_sel)
        {
        case SYS_FK_SEL_WORD:
            return 1;
        case SYS_FK_SEL_DWORD:
            return 2;
        case SYS_FK_SEL_QWORD:
            return 3;
        case SYS_FK_SEL_XAUXDATA:
            return 4;
        case SYS_FK_SEL_UDF_16BIT:
            return 5;
        case SYS_FK_SEL_UDF_32BIT:
            return 6;
        case SYS_FK_SEL_UDF_64BIT:
            return 7;
        case SYS_FK_SEL_UDF_128BIT:
            return 0;
        default :
            break;
        }
        return -1;
    }
    switch(fk_sel)
    {
    case SYS_FK_SEL_NIBBLE:
        return 1;
    case SYS_FK_SEL_BYTE:
        return 2;
    case SYS_FK_SEL_WORD:
        return 3;
    case SYS_FK_SEL_DWORD:
        return 4;
    case SYS_FK_SEL_QWORD:
    case SYS_FK_SEL_BYTE_DWORD:
        return 5;
    case SYS_FK_SEL_WORD_QWORD:
    case SYS_FK_SEL_WORD_DWORD:
    case SYS_FK_SEL_QWORD_LOW:
    case SYS_FK_SEL_XAUXDATA:
        return 6;
    case SYS_FK_SEL_NIBBLE_BYTE_QWORD:
    case SYS_FK_SEL_NIBBLE_WORD:
    case SYS_FK_SEL_DIRECT_AD:
        return 7;
    default :
        break;
    }
    return -1;
}



int32
_sys_xdata_fk_get_std_field_width(sys_xdata_std_field_t *self, sys_xdata_fk_f_db_t* pf_db_node)
{
    if (!SYS_SYS_XDATA_FK_IS_STD_FIELD(pf_db_node->father_field))
    {
        self->width = pf_db_node->bit_width;
        return SYS_XDATA_FK_NORMAL_FIELD;
    }
    self->width = pf_db_node->width;
    self->cur_index = pf_db_node->father_field - SYS_FK_F_XDATA_NIBBLE0;
    if (CTC_IS_BIT_SET(self->bitmap, self->cur_index))
    {
        return SYS_XDATA_FK_STD_FIELD_SET;
    }
    CTC_BIT_SET(self->bitmap, self->cur_index);
    return SYS_XDATA_FK_STD_FIELD_UNSET;
}


STATIC int32
_sys_usw_xdata_build_fk(uint8 lchip,sys_xdata_fk_db_t* p_fk_node)
{
    int32 ret = 0;
    XKeyGenProfile_m* fk_profile = &p_fk_node->p_std_field->profile;
    ctc_listnode_t*   node = NULL;
    sys_xdata_fk_f_db_t *pf_db_node = NULL;
    uint8 key_index[SYS_XDATA_WIDTH_NUM-1]= {0} ;
    uint8 l0_step = 0;
    uint8 total_bits = 0;
    uint8 key_gen_sel = 0;
    uint8 pre_key_gen_sel = 0;
    uint8 loop = 0;
    uint8 temp_data = 0;
    uint8 is_special_flow = 0;
    uint8 udf_width[2] = {4, 17};
    uint8 l1_sel[SYS_XDATA_WIDTH_NUM] = {0};
    uint16 offset = 0;
    uint16 mask_base = 0;  /* only valid for double append scl */
    uint16 flow_hash_base = 0; /* only valid for replace0 1 flow hash quad key */
    uint16 temp_offset = 0;
    uint16 udf_bitmap = 0;
    uint16 udf_offset = 0;
    uint16 replace_min_offset = 0;
    uint32 bit_vector = 0;
    uint32 mask = 0;
    uint32* p_mask = p_fk_node->p_std_field->mask;
    sys_xdata_std_field_t std_field;
    sys_xdata_fk_f_db_t std_field_db[SYS_FK_F_STD_FIELD_NUM];
    sys_xdata_fk_f_db_t *db_node[SYS_XDATA_WIDTH_NUM-1][SYS_FK_GEN_L0_PROF_NUM];
    sys_xdata_fk_f_db_t *udf_node[SYS_FK_UDF_NUM] = {NULL};

#define _SYS_XDATA_N_BASE    0
#define _SYS_XDATA_B_BASE    4
#define _SYS_XDATA_W_BASE    8
#define _SYS_XDATA_D_BASE    12
#define _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(max_value)    if (pre_key_gen_sel < max_value) { return CTC_E_NO_RESOURCE; }

    l0_step =  XKeyGenProfile_L0Profile_g_1_nibbleKeySel_f - XKeyGenProfile_L0Profile_g_0_nibbleKeySel_f;

    sal_memset(&std_field, 0, sizeof(sys_xdata_std_field_t));

    /*classify xpi field by width*/
    CTC_LIST_LOOP(p_fk_node->field_list, pf_db_node, node)
    {
        if (!pf_db_node->width)
        {
            if (SYS_FK_F_UDF_HIT_INDEX_LO == pf_db_node->field)
            {
                udf_node[0] = pf_db_node;
                CTC_BIT_SET(udf_bitmap, 0);
                pf_db_node->width = CTC_XDATA_WIDTH_4;
                pf_db_node->bit_width = CTC_XDATA_WIDTH_4;
                pf_db_node->mask = 0xf;
            }
            else if (SYS_FK_F_UDF_DATA0 <= pf_db_node->field && pf_db_node->field <= SYS_FK_F_UDF_DATA7)
            {
                udf_node[((pf_db_node->field-SYS_FK_F_UDF_DATA0)/2)+1] = pf_db_node;
                CTC_BIT_SET(udf_bitmap, ((pf_db_node->field-SYS_FK_F_UDF_DATA0)/2)+1);
                pf_db_node->width = 17;
                pf_db_node->bit_width = 17;
                pf_db_node->mask = 0x1ffff;
            }
            continue;
        }
        if(CTC_XDATA_LOCAL_TYPE_SCL == p_fk_node->type && 0xff == p_fk_node->hash_type && SYS_FK_MODE_APPEND == p_fk_node->mode)
        {
            bit_vector = 0xFFFF;
            total_bits = 128;
            continue;
        }
        ret = _sys_xdata_fk_get_std_field_width(&std_field, pf_db_node);
        switch(ret)
        {
        case SYS_XDATA_FK_STD_FIELD_SET:
            continue;
        case SYS_XDATA_FK_STD_FIELD_UNSET:
            sal_memcpy(&std_field_db[std_field.cur_index], pf_db_node, sizeof(sys_xdata_fk_f_db_t));
            std_field.pf_db_node[std_field.cur_index] = pf_db_node = &std_field_db[std_field.cur_index];
            break;
        default:
            break;
        }

        if (std_field.width == 4 && key_index[SYS_XDATA_WIDTH_NIBBLE] < SYS_FK_GEN_L0_PROF_NUM)
        {
            db_node[SYS_XDATA_WIDTH_NIBBLE][key_index[SYS_XDATA_WIDTH_NIBBLE]] = pf_db_node;
            SetXKeyGenProfile(V, L0Profile_g_0_nibbleKeySel_f + key_index[SYS_XDATA_WIDTH_NIBBLE]*l0_step,
                              fk_profile,  pf_db_node->pos_sel);
            total_bits += 4;
            CTC_BIT_SET(bit_vector, _SYS_XDATA_N_BASE + key_index[SYS_XDATA_WIDTH_NIBBLE]);

            key_index[SYS_XDATA_WIDTH_NIBBLE]++;
        }
        else if(std_field.width == 8 && key_index[SYS_XDATA_WIDTH_BYTE] < SYS_FK_GEN_L0_PROF_NUM)
        {
            db_node[SYS_XDATA_WIDTH_BYTE][key_index[SYS_XDATA_WIDTH_BYTE]] = pf_db_node;
            SetXKeyGenProfile(V, L0Profile_g_0_byteKeySel_f + key_index[SYS_XDATA_WIDTH_BYTE]*l0_step,
                              fk_profile,  pf_db_node->pos_sel/2);
            total_bits += 8;
            CTC_BIT_SET(bit_vector, _SYS_XDATA_B_BASE + key_index[SYS_XDATA_WIDTH_BYTE]);
            key_index[SYS_XDATA_WIDTH_BYTE]++;
        }
        else if(std_field.width == 16 && key_index[SYS_XDATA_WIDTH_WORD] < SYS_FK_GEN_L0_PROF_NUM)
        {
            db_node[SYS_XDATA_WIDTH_WORD][key_index[SYS_XDATA_WIDTH_WORD]] = pf_db_node;
            SetXKeyGenProfile(V, L0Profile_g_0_wordKeySel_f + key_index[SYS_XDATA_WIDTH_WORD]*l0_step,
                              fk_profile,  pf_db_node->pos_sel/4);
            total_bits += 16;
            CTC_BIT_SET(bit_vector, _SYS_XDATA_W_BASE + key_index[SYS_XDATA_WIDTH_WORD]);
            key_index[SYS_XDATA_WIDTH_WORD]++;
        }
        else if(std_field.width == 32 && key_index[SYS_XDATA_WIDTH_DWORD] < SYS_FK_GEN_L0_PROF_NUM)
        {
            db_node[SYS_XDATA_WIDTH_DWORD][key_index[SYS_XDATA_WIDTH_DWORD]] = pf_db_node;
            SetXKeyGenProfile(V, L0Profile_g_0_dwordKeySel_f + key_index[SYS_XDATA_WIDTH_DWORD]*l0_step,
                              fk_profile,  pf_db_node->pos_sel/8);
            total_bits += 32;
            CTC_BIT_SET(bit_vector, _SYS_XDATA_D_BASE + key_index[SYS_XDATA_WIDTH_DWORD]);
            key_index[SYS_XDATA_WIDTH_DWORD]++;
        }
        else
        {
            return CTC_E_NO_RESOURCE;
        }
    }

    if (SYS_XDATA_LOCAL_TYPE_XHASH != p_fk_node->type)
    {
        CTC_ERROR_RETURN(_sys_usw_xdata_get_fk_field_offset(lchip, p_fk_node, &offset, &udf_offset, &replace_min_offset, total_bits));
        is_special_flow = (p_fk_node->mode != SYS_FK_MODE_APPEND && CTC_XDATA_LOCAL_TYPE_FLOW_HASH == p_fk_node->type && p_fk_node->key_size == SYS_FK_SIZE_QUAD);

        if (p_fk_node->mode == SYS_FK_MODE_REPLACE1 && !is_special_flow)
        {
            for (loop=0; loop<replace_min_offset/CTC_UINT32_BITS; loop++)
            {
                p_mask[loop] = CTC_MAX_UINT32_VALUE;
            }
            temp_data = replace_min_offset%CTC_UINT32_BITS;
            if (0 != temp_data)
            {
                p_mask[loop] |= (1<<temp_data) - 1;
            }
        }
        if (p_fk_node->mode == SYS_FK_MODE_APPEND && CTC_XDATA_LOCAL_TYPE_SCL == p_fk_node->type)
        {
            mask_base = p_fk_node->key_size ? 143 : 63;/* need mask origin key field, default all F */
            CTC_BMP_SET_RANGE(p_mask, 0, mask_base-1);
        }

        /*
        if (p_fk_node->mode == SYS_FK_MODE_REPLACE2)
        {
            mask_offset = (offset<replace_min_offset ? offset : replace_min_offset) / CTC_UINT32_BITS;
            for (loop=0; loop<mask_offset; loop++)
            {
                p_fk_node->mask->mask[loop] = 0;
            }
            temp_data = mask_offset % CTC_UINT32_BITS;
            if (0 != temp_data)
            {
                p_fk_node->mask->mask[loop] &= ~((1<<temp_data) - 1);
            }
        }
        */
    }

    if (p_fk_node->type == CTC_XDATA_LOCAL_TYPE_SCL)
    {
        pre_key_gen_sel = _sys_usw_xdata_get_scl_presel(lchip, p_fk_node, udf_bitmap, bit_vector);
    }
    else
    {
        pre_key_gen_sel = SYS_FK_SEL_ALL;
    }

    if (p_fk_node->mode == SYS_FK_MODE_APPEND && (p_fk_node->type == CTC_XDATA_LOCAL_TYPE_IPFIX || p_fk_node->type == CTC_XDATA_LOCAL_TYPE_EGS_IPFIX))
    {
        p_fk_node->key_sel = (p_fk_node->key_size == SYS_FK_SIZE_SINGLE) ? 1 : 3;
        CTC_LIST_LOOP(p_fk_node->field_list, pf_db_node, node)
        {
            pf_db_node->drv_offset = offset + pf_db_node->pos_sel*4+pf_db_node->start_bit;
            mask = pf_db_node->mask;
            CTC_BMP_COPY_RANGE(p_mask, pf_db_node->drv_offset,&mask, pf_db_node->start_bit, pf_db_node->bit_width);
        }
        return CTC_E_NONE;
    }
    temp_offset = offset;
    if(is_special_flow)
    {
        flow_hash_base = offset;
    }

    /*TODO no consider group*/
    #define SYS_FK_CHECK_OFFSET(offset_max)\
        temp_offset -= (offset_max-total_bits);\
        if(p_fk_node->mode != SYS_FK_MODE_APPEND)\
        {\
            offset = temp_offset;\
        }\
        if(is_special_flow)\
        {\
            flow_hash_base = offset;\
        }\
        if (p_fk_node->mode == SYS_FK_MODE_REPLACE1 && temp_offset < replace_min_offset)\
        {\
            return CTC_E_NO_RESOURCE;\
        }
    #define SYS_FK_BMP_SEL(bit_vector,fk_bmp)   (0 == (bit_vector & (~fk_bmp)))
    #define SYS_FK_SET_DRV_OFFSET(width,index)    \
        do{ \
            uint32 _value_ = 0; \
            uint8 _width_ = 1<<(2+width);   \
            if (bit_vector & (1<<(4*width+index)))   {   \
                db_node[width][index]->drv_offset = offset; \
                mask = db_node[width][index]->mask;\
                CTC_BMP_COPY_RANGE(p_mask, (mask_base+offset-flow_hash_base+db_node[width][index]->start_bit), &mask, db_node[width][index]->start_bit, db_node[width][index]->bit_width);\
            } else {    \
                CTC_BMP_COPY_RANGE(p_mask, (mask_base+offset-flow_hash_base), &_value_, 0, _width_);\
            }\
            offset += _width_;   \
        }while(0)

    if (bit_vector == 0x0001 || !bit_vector)   /*Nibble Select*/
    {   //XKeySet.nibbleKey(3,0)  1 4Bits   TempXKeyBus.g[XKeyGenL1Profile.nibbleKeySel].nibbleKey(3,0);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_NIBBLE);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_NIBBLE);
        l1_sel[SYS_XDATA_WIDTH_NIBBLE] = 0;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,0);
    }
    else if (bit_vector == 0x0010)  /*Byte Select*/
    {   //XKeySet.byteKey(7,0)   1 8Bits  TempXKeyBus.g[XKeyGenL1Profile.byteKeySel(1,0)].byteKey(7,0);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_BYTE);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_BYTE);
        l1_sel[SYS_XDATA_WIDTH_BYTE] = 0;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
    }
    else if (bit_vector == 0x0100)  /*Word Select*/
    {   //XKeySet.wordKey(15,0)   TempXKeyBus.g[XKeyGenL1Profile.wordKeySel(0)].wordKey(15,0);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_WORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,p_fk_node->is_direct_key ? SYS_FK_SEL_DIRECT_AD:SYS_FK_SEL_WORD);
        l1_sel[SYS_XDATA_WIDTH_WORD] = 0;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
    }
    else if (bit_vector == 0x1000)  /*DWord Select*/
    {   //XKeySet.dwordKey(31,0) TempXKeyBus.g[XKeyGenL1Profile.dwordkeySel(0)].dwordKey(31,0);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_DWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_DWORD);
        l1_sel[SYS_XDATA_WIDTH_DWORD] = 0;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,0);
    }
    else if (bit_vector == 0x0003)  /*Byte Select*/
    {   //XKeySet.byteKey(7,0)   2 4Bits  (TempXKeyBus.g[1].nibbleKey(3,0),TempXKeyBus.g[0].nibbleKey(3,0));
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_BYTE);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_BYTE);
        l1_sel[SYS_XDATA_WIDTH_BYTE] = 3;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,1);
    }
    else if (bit_vector == 0x0030)  /*Word Select*/
    {   //XKeySet.wordKey(15,0)  (TempXKeyBus.g[1].byteKey(7,0),TempXKeyBus.g[0].byteKey(7,0));
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_WORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_WORD);
        l1_sel[SYS_XDATA_WIDTH_WORD] = 2;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,1);
    }
    else if (bit_vector == 0x0300)  /*DWord Select*/
    {   //XKeySet.dwordKey(31,0)  (TempXKeyBus.g[1].wordKey(15,0),TempXKeyBus.g[0].wordKey(15,0));
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_DWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_DWORD);
        l1_sel[SYS_XDATA_WIDTH_DWORD] = 2;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,1);
    }
    else if (bit_vector == 0x3000)  /*QWord Select*/
    {   //XKeySet.dwordKey(63,0)  (TempXKeyBus.g[1].dwordKey(31,0),TempXKeyBus.g[0].dwordKey(31,0));
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_QWORD);
        if (p_fk_node->type == CTC_XDATA_LOCAL_TYPE_SCL
            && p_fk_node->mode == SYS_FK_MODE_REPLACE1
            && p_fk_node->key_size == SYS_FK_SIZE_SINGLE)
        {
            return CTC_E_NOT_SUPPORT;
        }
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_QWORD);
        l1_sel[SYS_XDATA_WIDTH_QWORD] = 0;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,1);
    }
#if 0
    else if (bit_vector == 0x0303)  /*DWord + Byte Select*/
    {   //XKeySet.dwordKey(31,0) XKeySet.byteKey(7,0);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_BYTE_DWORD);

        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_BYTE_DWORD);
        l1_sel[SYS_XDATA_WIDTH_DWORD] = 2;
        l1_sel[SYS_XDATA_WIDTH_BYTE] = 3;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,1);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,1);
    }
#endif
    else if (SYS_FK_BMP_SEL(bit_vector,0x0013))   /*Word Select*/
    {   //XKeySet.wordKey(15,0)  (TempXKeyBus.g[1].nibbleKey(3,0),TempXKeyBus.g[0].nibbleKey(3,0),TempXKeyBus.g[XKeyGenL1Profile.wordKeySel(0)].byteKey(7,0));
        SYS_FK_CHECK_OFFSET(16);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_WORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_WORD);
        l1_sel[SYS_XDATA_WIDTH_WORD] = 4;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,1);
    }
    else if (SYS_FK_BMP_SEL(bit_vector,0x0033))   /*DWord Select*/
    {   //XKeySet.dwordKey(31,0)    (CBit(8, 'd', "0", 1),TempXKeyBus.g[1].nibbleKey(3,0),TempXKeyBus.g[0].nibbleKey(3,0),TempXKeyBus.g[1].byteKey(7,0),TempXKeyBus.g[0].byteKey(7,0));
        SYS_FK_CHECK_OFFSET(32);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_DWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_DWORD);
        l1_sel[SYS_XDATA_WIDTH_DWORD] = 3;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE, 0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE, 1);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE, 0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE, 1);
    }
#if 0 /* low bit replac */
    else if (SYS_FK_BMP_SEL(bit_vector,0x0101))   /*WORD + NIBBLE*/
    {
        temp_offset -= (20-total_bits);
        if (p_fk_node->mode == SYS_FK_MODE_REPLACE1 && temp_offset < replace_min_offset)
        {
            return CTC_E_NO_RESOURCE;
        }
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_DWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_NIBBLE_WORD);
        l1_sel[SYS_XDATA_WIDTH_WORD] = 0;
        l1_sel[SYS_XDATA_WIDTH_NIBBLE] = 0;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,0);
    }
#endif
    else if (SYS_FK_BMP_SEL(bit_vector,0x0113))   /*DWord Select*/
    {   //XKeySet.dwordKey(31,0)  (TempXKeyBus.g[1].nibbleKey(3,0),TempXKeyBus.g[0].nibbleKey(3,0),TempXKeyBus.g[0].byteKey(7,0),TempXKeyBus.g[XKeyGenL1Profile.dwordkeySel(0)].wordKey(15,0));
        SYS_FK_CHECK_OFFSET(32);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_DWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_DWORD);
        l1_sel[SYS_XDATA_WIDTH_DWORD] = 6;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,1);
    }
    else if (SYS_FK_BMP_SEL(bit_vector,0x0130))   /*DWord Select*/
    {   //XKeySet.dwordKey(31,0)  (TempXKeyBus.g[1].byteKey(7,0),TempXKeyBus.g[0].byteKey(7,0),TempXKeyBus.g[XKeyGenL1Profile.dwordkeySel(0)].wordKey(15,0));
        SYS_FK_CHECK_OFFSET(32);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_DWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_DWORD);
        l1_sel[SYS_XDATA_WIDTH_DWORD] = 4;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,1);
    }
    else if (SYS_FK_BMP_SEL(bit_vector,0x0333))   /*QWord Select*/
    {   //XKeySet.dwordKey(63,0)    (CBit(8, 'd', "0", 1),TempXKeyBus.g[1].nibbleKey(3,0),TempXKeyBus.g[0].nibbleKey(3,0),TempXKeyBus.g[1].byteKey(7,0),TempXKeyBus.g[0].byteKey(7,0),TempXKeyBus.g[1].wordKey(15,0),TempXKeyBus.g[0].wordKey(15,0));
        SYS_FK_CHECK_OFFSET(64);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_QWORD);
        key_gen_sel = SYS_FK_SEL_QWORD;
        if (p_fk_node->type == CTC_XDATA_LOCAL_TYPE_SCL
            && p_fk_node->mode == SYS_FK_MODE_REPLACE1
            && p_fk_node->key_size == SYS_FK_SIZE_SINGLE)
        {
            if (bit_vector & 0x0102)
            {
                return CTC_E_NOT_SUPPORT;
            }
            if (bit_vector & 0x0100)
            {
                key_gen_sel = SYS_FK_SEL_QWORD_LOW;
                offset += 1;
            }
        }
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,key_gen_sel);
        l1_sel[SYS_XDATA_WIDTH_QWORD] = 1;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,1);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,1);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,1);
    }
    else if (SYS_FK_BMP_SEL(bit_vector,0x1300))   /*QWord Select*/
    {   //XKeySet.dwordKey(63,0)  (TempXKeyBus.g[1].wordKey(15,0),TempXKeyBus.g[0].wordKey(15,0),TempXKeyBus.g[XKeyGenL1Profile.qwordSel(0)].dwordKey(31,0));
        SYS_FK_CHECK_OFFSET(64);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_QWORD);
        key_gen_sel = SYS_FK_SEL_QWORD;
        if (p_fk_node->type == CTC_XDATA_LOCAL_TYPE_SCL
            && p_fk_node->mode == SYS_FK_MODE_REPLACE1
            && p_fk_node->key_size == SYS_FK_SIZE_SINGLE)
        {
            if (bit_vector & 0x1200)
            {
                return CTC_E_NOT_SUPPORT;
            }
            key_gen_sel = SYS_FK_SEL_QWORD_LOW;
            offset += 1;
        }
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,key_gen_sel);
        l1_sel[SYS_XDATA_WIDTH_QWORD] = 2;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,1);
    }
    else if (SYS_FK_BMP_SEL(bit_vector,0x0031))   /*WORD + NIBBLE*/
    {
        SYS_FK_CHECK_OFFSET(20);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_DWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_NIBBLE_WORD);
        l1_sel[SYS_XDATA_WIDTH_WORD] = 2;
        l1_sel[SYS_XDATA_WIDTH_NIBBLE] = 0;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,1);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,0);
    }
    else if (SYS_FK_BMP_SEL(bit_vector,0x3100))   /*QWORD + WORD*/
    {
        SYS_FK_CHECK_OFFSET(80);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_WORD_QWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_WORD_QWORD);
        l1_sel[SYS_XDATA_WIDTH_QWORD] = 0;
        l1_sel[SYS_XDATA_WIDTH_WORD] = 0;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,1);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
    }
    else if (SYS_FK_BMP_SEL(bit_vector,0x3030))   /*QWORD + WORD*/
    {
        SYS_FK_CHECK_OFFSET(80);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_WORD_QWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_WORD_QWORD);
        l1_sel[SYS_XDATA_WIDTH_QWORD] = 0;
        l1_sel[SYS_XDATA_WIDTH_WORD] = 2;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,1);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,1);
    }
    else if (SYS_FK_BMP_SEL(bit_vector,0x1330))   /*QWORD + WORD*/
    {
        SYS_FK_CHECK_OFFSET(80);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_WORD_QWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_WORD_QWORD);
        l1_sel[SYS_XDATA_WIDTH_QWORD] = 2;
        l1_sel[SYS_XDATA_WIDTH_WORD] = 2;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,1);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,1);
    }
    else if (SYS_FK_BMP_SEL(bit_vector,0x3013))   /*QWORD + WORD*/
    {
        SYS_FK_CHECK_OFFSET(80);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_WORD_QWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_WORD_QWORD);
        l1_sel[SYS_XDATA_WIDTH_QWORD] = 0;
        l1_sel[SYS_XDATA_WIDTH_WORD] = 4;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,1);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,1);
    }
    else if (SYS_FK_BMP_SEL(bit_vector,0x1313))   /*QWORD + WORD*/
    {
        SYS_FK_CHECK_OFFSET(80);
        _SYS_XDATA_PRE_KEY_GEN_SEL_CHECK(SYS_FK_SEL_WORD_QWORD);
        key_gen_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_WORD_QWORD);
        l1_sel[SYS_XDATA_WIDTH_QWORD] = 2;
        l1_sel[SYS_XDATA_WIDTH_WORD] = 4;
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_DWORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_WORD,1);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_BYTE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,0);
        SYS_FK_SET_DRV_OFFSET(SYS_XDATA_WIDTH_NIBBLE,1);
    }
    else/*auxdata(127,0) AT_TODO*/
    {
        p_fk_node->key_sel = _sys_usw_xdata_get_fk_sel(lchip,p_fk_node->type,SYS_FK_SEL_XAUXDATA);
        CTC_LIST_LOOP(p_fk_node->field_list, pf_db_node, node)
        {
            pf_db_node->drv_offset = offset + pf_db_node->pos_sel*4+pf_db_node->start_bit;
            CTC_BMP_SET_RANGE(p_mask, (mask_base+pf_db_node->drv_offset-flow_hash_base), pf_db_node->bit_width);
        }
    }

    SetXKeyGenProfile(V, L1Profile_nibbleKeySel_f,  fk_profile, l1_sel[SYS_XDATA_WIDTH_NIBBLE]);
    SetXKeyGenProfile(V, L1Profile_byteKeySel_f,    fk_profile, l1_sel[SYS_XDATA_WIDTH_BYTE]);
    SetXKeyGenProfile(V, L1Profile_wordKeySel_f,    fk_profile, l1_sel[SYS_XDATA_WIDTH_WORD]);
    SetXKeyGenProfile(V, L1Profile_dwordkeySel_f,   fk_profile, l1_sel[SYS_XDATA_WIDTH_DWORD]);
    SetXKeyGenProfile(V, L1Profile_qwordSel_f,      fk_profile, l1_sel[SYS_XDATA_WIDTH_QWORD]);

    if (p_fk_node->type == CTC_XDATA_LOCAL_TYPE_SCL && 0 != p_fk_node->udf_en)
    {
        if(!total_bits && SYS_FK_MODE_APPEND != p_fk_node->mode)/* only have udf field */
        {
            udf_offset -= 4;
        }
        for (loop=0; loop<SYS_FK_UDF_NUM; loop++)
        {
            udf_offset -= udf_width[loop>0 ? 1 : 0];
            if (!udf_node[loop])
            {
                continue;
            }

            if ((SYS_FK_MODE_REPLACE1 == p_fk_node->mode && udf_offset < replace_min_offset) ||
                (SYS_FK_MODE_APPEND == p_fk_node->mode && 0xff == p_fk_node->hash_type && udf_offset < 128))/* SCL Tcam double append */
            {
                return CTC_E_NO_RESOURCE;
            }
            udf_node[loop]->drv_offset = udf_offset;
            CTC_BMP_SET_RANGE(p_mask, (mask_base+udf_node[loop]->drv_offset), udf_node[loop]->bit_width);
        }
    }
    if (0 != std_field.bitmap)
    {
        CTC_LIST_LOOP(p_fk_node->field_list, pf_db_node, node)
        {
            if (!SYS_SYS_XDATA_FK_IS_STD_FIELD(pf_db_node->father_field))
            {
                continue;
            }

            std_field.cur_index = pf_db_node->father_field - SYS_FK_F_XDATA_NIBBLE0;
            pf_db_node->drv_offset = \
                std_field.pf_db_node[std_field.cur_index]->drv_offset + pf_db_node->start_bit;
            CTC_BMP_SET_RANGE(p_mask, (mask_base+pf_db_node->drv_offset-flow_hash_base), pf_db_node->bit_width);
            if(SYS_FK_F_XDATA == pf_db_node->field)
            {
                mask = pf_db_node->mask;
                CTC_BMP_COPY_RANGE(p_mask, (mask_base+pf_db_node->drv_offset-flow_hash_base), &mask, 0, pf_db_node->width);
            }
        }
    }

    p_fk_node->key_sel = key_gen_sel;

    return 0;
}



STATIC int32
_sys_usw_xdata_install_fk(uint8 lchip, sys_xdata_fk_db_t *p_fk_node, uint8 is_install)
{
    XKeyGenProfile_m* fk_profile = &p_fk_node->p_std_field->profile;
    uint32* fk_mask = p_fk_node->p_std_field->mask;
    uint32 cmd = 0;
    uint32 mask[5] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
    uint8 hash_type = 0, lkup_level = 0;
    uint8 step = 0;
    uint8 size_step = 0;
    union
    {
        UserIdXCtl_m                userid_xctl;
        FibEngineLookupXCtl_m       fib_xctl;
        IpfixEngineXCtl_m           ipfix_xctl;
        EgrSclHashXCtl_m            escl_xctl;
        EgressSclHashLookupCtl_m    escl_lkup_ctl;
        IpeHashXHashGenCtl_m        ipe_xhash_ctl;
    } ds;

#define _SYS_FK_SET_V(value)  (is_install ? value : 0)

    if (CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT != p_fk_node->type)
    {
        if (-1 == _sys_usw_xdata_get_hash_info(lchip, p_fk_node->tbl_id, &hash_type))
        {
            _sys_usw_xdata_get_tcam_info(lchip, p_fk_node->tbl_id, &hash_type);
        }
    }

    switch(p_fk_node->type)
    {
    case CTC_XDATA_LOCAL_TYPE_SCL:
        {
            cmd = DRV_IOR(UserIdXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            if (0xFF == p_fk_node->hash_type)
            {
                step = UserIdXCtl_gXTcamkey_1_enable_f - UserIdXCtl_gXTcamkey_0_enable_f;
                SetUserIdXCtl(V, gXTcamkey_0_enable_f + hash_type*step, &ds, _SYS_FK_SET_V(1));
                SetUserIdXCtl(V, gXTcamkey_0_index_f + hash_type*step, &ds, _SYS_FK_SET_V(p_fk_node->fk_prof_id));
            }
            else
            {
                size_step = (p_fk_node->mode == SYS_FK_MODE_APPEND)? 1: 0;
                step = UserIdXCtl_gXHashkey_1_enable_f - UserIdXCtl_gXHashkey_0_enable_f;
                SetUserIdXCtl(V, gXHashkey_0_enable_f + hash_type*step, &ds, _SYS_FK_SET_V(1));
                SetUserIdXCtl(V, gXHashkey_0_index_f + hash_type*step, &ds, _SYS_FK_SET_V(p_fk_node->fk_prof_id));
                switch(p_fk_node->key_size + size_step)
                {
                case SYS_FK_SIZE_SINGLE:
                    step = UserIdXCtl_gXKeyMask_1_data_f - UserIdXCtl_gXKeyMask_0_data_f;
                    SetUserIdXCtl(A, gXKeyMask_0_data_f + step*p_fk_node->fk_mask_id, &ds, fk_mask);
                    break;
                case SYS_FK_SIZE_DOUBLE:
                    step = UserIdXCtl_gXKeyMask_1_data_f - UserIdXCtl_gXKeyMask_0_data_f;
                    SetUserIdXCtl(A, gXKeyMask_0_data_f + step*p_fk_node->fk_mask_id, &ds, fk_mask);
                    CTC_BMP_COPY_RANGE(mask,0,fk_mask,_SYS_FK_MASK_80BITS,_SYS_FK_MASK_80BITS);
                    SetUserIdXCtl(A, gXKeyMask_0_data_f + step*(p_fk_node->fk_mask_id+1), &ds, mask);
                    break;
                case SYS_FK_SIZE_QUAD:
                default:
                    step = UserIdXCtl_gXKeyMask_1_data_f - UserIdXCtl_gXKeyMask_0_data_f;
                    SetUserIdXCtl(A, gXKeyMask_0_data_f + step*p_fk_node->fk_mask_id, &ds, fk_mask);
                    CTC_BMP_COPY_RANGE(mask,0,fk_mask,_SYS_FK_MASK_80BITS,_SYS_FK_MASK_80BITS);
                    SetUserIdXCtl(A, gXKeyMask_0_data_f + step*(p_fk_node->fk_mask_id+1), &ds, mask);
                    CTC_BMP_COPY_RANGE(mask,0,fk_mask,2*_SYS_FK_MASK_80BITS,_SYS_FK_MASK_80BITS);
                    SetUserIdXCtl(A, gXKeyMask_0_data_f + step*(p_fk_node->fk_mask_id+2), &ds, mask);
                    CTC_BMP_COPY_RANGE(mask,0,fk_mask,3*_SYS_FK_MASK_80BITS,_SYS_FK_MASK_80BITS);
                    SetUserIdXCtl(A, gXKeyMask_0_data_f + step*(p_fk_node->fk_mask_id+3), &ds, mask);
                    break;
                }
                step = UserIdXCtl_gXKeyGen_1_index_f - UserIdXCtl_gXKeyGen_0_index_f;
                SetUserIdXCtl(V, gXKeyGen_0_index_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->fk_mask_id);
            }
            SetUserIdXCtl(V, gXKeyGen_0_keyMode_f + p_fk_node->fk_prof_id*step, &ds, (1 == p_fk_node->mode)? 1: 0);
            SetUserIdXCtl(V, gXKeyGen_0_keySel_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->key_sel);
            SetUserIdXCtl(A, gXKeyGen_0_profile_f + p_fk_node->fk_prof_id*step, &ds, fk_profile);
            SetUserIdXCtl(V, gXKeyGen_0_udfEn_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->udf_en);
            SetUserIdXCtl(V, gXKeyGen_0_udfDataEn_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->udf_bmp);

            cmd = DRV_IOW(UserIdXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        }
        break;

    case CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT:
        {
            hash_type = p_fk_node->hash_type;
            lkup_level = (p_fk_node->tbl_id == DsXLookup0HashKey_t ? 0 : 1);
            cmd = DRV_IOR(FibEngineLookupXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            step = FibEngineLookupXCtl_gXLookup_1_typeSel_f - FibEngineLookupXCtl_gXLookup_0_typeSel_f;
            SetFibEngineLookupXCtl(V, gXLookup_0_typeSel_f + lkup_level*step, &ds, _SYS_FK_SET_V(p_fk_node->type_sel));
            SetFibEngineLookupXCtl(V, gXLookup_0_typeValue_f + lkup_level*step, &ds, _SYS_FK_SET_V(0xFE));

            step = FibEngineLookupXCtl_gXLookupType_1_value_f - FibEngineLookupXCtl_gXLookupType_0_value_f;
            SetFibEngineLookupXCtl(V, gXLookupType_0_value_f + ((lkup_level<<3)|hash_type)*step, &ds, _SYS_FK_SET_V(hash_type));

            step = FibEngineLookupXCtl_gXHashkey_1_enable_f - FibEngineLookupXCtl_gXHashkey_0_enable_f;
            SetFibEngineLookupXCtl(V, gXHashkey_0_xLookupKeyEn_f + hash_type*step, &ds, _SYS_FK_SET_V(1));
            SetFibEngineLookupXCtl(V, gXHashkey_0_index_f + hash_type*step, &ds, _SYS_FK_SET_V(p_fk_node->fk_prof_id));

            step = FibEngineLookupXCtl_gXKeyGen_1_index_f - FibEngineLookupXCtl_gXKeyGen_0_index_f;
            SetFibEngineLookupXCtl(V, gXKeyGen_0_index_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->fk_mask_id>>1);
            SetFibEngineLookupXCtl(V, gXKeyGen_0_subIndex_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->fk_mask_id&1);
            SetFibEngineLookupXCtl(V, gXKeyGen_0_keyMode_f + p_fk_node->fk_prof_id*step, &ds, (1 == p_fk_node->mode)?1:0 );
            SetFibEngineLookupXCtl(V, gXKeyGen_0_keySel_f + p_fk_node->fk_prof_id*step, &ds, _SYS_FK_SET_V(p_fk_node->key_sel));
            SetFibEngineLookupXCtl(A, gXKeyGen_0_profile_f + p_fk_node->fk_prof_id*step, &ds, fk_profile);

            step = FibEngineLookupXCtl_gXKeyMask_1_data_f - FibEngineLookupXCtl_gXKeyMask_0_data_f;
            GetFibEngineLookupXCtl(A, gXKeyMask_0_data_f + step*(p_fk_node->fk_mask_id>>1), &ds, mask);
            CTC_BMP_COPY_RANGE(mask, _SYS_FK_MASK_80BITS*(p_fk_node->fk_mask_id&1),
                               fk_mask, 0, _SYS_FK_MASK_80BITS);
            SetFibEngineLookupXCtl(A, gXKeyMask_0_data_f + step*(p_fk_node->fk_mask_id>>1), &ds, mask);

            cmd = DRV_IOW(FibEngineLookupXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        }
        break;

    case CTC_XDATA_LOCAL_TYPE_FLOW_HASH:
        {
            cmd = DRV_IOR(FibEngineLookupXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            step = FibEngineLookupXCtl_gXHashkey_1_enable_f - FibEngineLookupXCtl_gXHashkey_0_enable_f;
            SetFibEngineLookupXCtl(V, gXHashkey_0_enable_f + hash_type*step, &ds, _SYS_FK_SET_V(1));
            SetFibEngineLookupXCtl(V, gXHashkey_0_index_f + hash_type*step, &ds, _SYS_FK_SET_V(p_fk_node->fk_prof_id));

            step = FibEngineLookupXCtl_gXKeyGen_1_index_f - FibEngineLookupXCtl_gXKeyGen_0_index_f;
            SetFibEngineLookupXCtl(V, gXKeyGen_0_index_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->fk_mask_id);
            SetFibEngineLookupXCtl(V, gXKeyGen_0_keyMode_f + p_fk_node->fk_prof_id*step, &ds, (1 == p_fk_node->mode)?1:0 );
            SetFibEngineLookupXCtl(V, gXKeyGen_0_keySel_f + p_fk_node->fk_prof_id*step, &ds, _SYS_FK_SET_V(p_fk_node->key_sel));
            SetFibEngineLookupXCtl(A, gXKeyGen_0_profile_f + p_fk_node->fk_prof_id*step, &ds, fk_profile);

            step = FibEngineLookupXCtl_gXKeyMask_1_data_f - FibEngineLookupXCtl_gXKeyMask_0_data_f;
            SetFibEngineLookupXCtl(A, gXKeyMask_0_data_f + step*(p_fk_node->fk_mask_id), &ds, fk_mask);

            cmd = DRV_IOW(FibEngineLookupXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        }

        break;
#if 0
    case SYS_XDATA_LOCAL_TYPE_XHASH:
        {
            cmd = DRV_IOR(IpeHashXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            step = IpeHashXCtl_gXHash_1_hashMode_f - IpeHashXCtl_gXHash_0_hashMode_f;
            /*
            SetIpeHashXCtl(V, xHashTypeSel_f, &ds, _SYS_FK_SET_V(p_fk_node->type_sel));
            SetIpeHashXCtl(V, xHashEn_f, &ds, _SYS_FK_SET_V(1));
            hash_type -> field_select_id
            */
            SetIpeHashXCtl(V, gXHash_0_hashMode_f + hash_type*step, &ds, _SYS_FK_SET_V(3));
            SetIpeHashXCtl(V, gXHash_0_hashInnerEn_f + hash_type*step, &ds, 0);
            SetIpeHashXCtl(V, gXHash_0_profileId_f + hash_type*step, &ds, _SYS_FK_SET_V(p_fk_node->fk_prof_id));

            step = IpeHashXCtl_gXPacket_1_enable_f - IpeHashXCtl_gXPacket_0_enable_f;
            SetIpeHashXCtl(V, gXPacket_0_enable_f + (hash_type<<3)*step, &ds, 0);
            /*
            SetIpeHashXCtl(V, gXPacket_0_maskId_f + (hash_type<<3)*step, &ds, 0);
            step = IpeHashXCtl_gXMask_1_bitmap_f - IpeHashXCtl_gXMask_0_bitmap_f;
            SetIpeHashXCtl(V, gXMask_0_bitmap_f + (mask_id)*step, &ds, 0);
            */

            cmd = DRV_IOW(IpeHashXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            cmd = DRV_IOR(IpeHashXHashGenCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_fk_node->fk_prof_id, cmd, &ds));
            SetTempInfoHashXCtl(V, keySel_f, &ds, _SYS_FK_SET_V(p_fk_node->key_sel));
            SetTempInfoHashXCtl(V, bitmapOpMode_f, &ds, 0);
            SetTempInfoHashXCtl(V, bulkId_f, &ds, 0);
            SetTempInfoHashXCtl(V, bitmap_f, &ds, _SYS_FK_SET_V(0xFFFF));
            SetTempInfoHashXCtl(A, profile_f, &ds, fk_profile);
            cmd = DRV_IOW(IpeHashXHashGenCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_fk_node->fk_prof_id, cmd, &ds));
        }
        break;
#endif
    case CTC_XDATA_LOCAL_TYPE_IPFIX:
    {
        IpfixEngineXKeyMaskCtl_m xkey_mask_ctl;
        cmd = DRV_IOR(IpfixEngineXCtl0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

        step = IpfixEngineXCtl0_gXHashkey_1_enable_f - IpfixEngineXCtl0_gXHashkey_0_enable_f;
        SetIpfixEngineXCtl(V, gXHashkey_0_enable_f + hash_type*step, &ds, _SYS_FK_SET_V(1));
        SetIpfixEngineXCtl(V, gXHashkey_0_keyMode_f + hash_type*step, &ds,  (1 == p_fk_node->mode)? 1: 0 );
        SetIpfixEngineXCtl(V, gXHashkey_0_index_f + hash_type*step, &ds, _SYS_FK_SET_V(p_fk_node->fk_prof_id));

        step = IpfixEngineXCtl0_gXKeyGen_1_index_f - IpfixEngineXCtl0_gXKeyGen_0_index_f;
        SetIpfixEngineXCtl(V, gXKeyGen_0_index_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->fk_mask_id);
        SetIpfixEngineXCtl(V, gXKeyGen_0_keyMode_f + p_fk_node->fk_prof_id*step, &ds, (1 == p_fk_node->mode)? 1: 0 );
        SetIpfixEngineXCtl(V, gXKeyGen_0_keySel_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->key_sel);
        SetIpfixEngineXCtl(A, gXKeyGen_0_profile_f + p_fk_node->fk_prof_id*step, &ds, fk_profile);

        cmd = DRV_IOW(IpfixEngineXCtl0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

        cmd = DRV_IOR(IpfixEngineXKeyMaskCtl0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_fk_node->fk_mask_id, cmd, &xkey_mask_ctl));
        SetIpfixEngineXKeyMaskCtl(A, data_f, &xkey_mask_ctl, fk_mask);
        cmd = DRV_IOW(IpfixEngineXKeyMaskCtl0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_fk_node->fk_mask_id, cmd, &xkey_mask_ctl));
    }
    break;

    case CTC_XDATA_LOCAL_TYPE_EGS_IPFIX:
    {
        IpfixEngineXKeyMaskCtl_m xkey_mask_ctl;
        cmd = DRV_IOR(IpfixEngineXCtl1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

        step = IpfixEngineXCtl1_gXHashkey_1_enable_f - IpfixEngineXCtl1_gXHashkey_0_enable_f;
        SetIpfixEngineXCtl(V, gXHashkey_0_enable_f + hash_type*step, &ds, _SYS_FK_SET_V(1));
        SetIpfixEngineXCtl(V, gXHashkey_0_keyMode_f + hash_type*step, &ds,  (1 == p_fk_node->mode)? 1: 0 );
        SetIpfixEngineXCtl(V, gXHashkey_0_index_f + hash_type*step, &ds, _SYS_FK_SET_V(p_fk_node->fk_prof_id));

        step = IpfixEngineXCtl1_gXKeyGen_1_index_f - IpfixEngineXCtl1_gXKeyGen_0_index_f;
        SetIpfixEngineXCtl(V, gXKeyGen_0_index_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->fk_mask_id);
        SetIpfixEngineXCtl(V, gXKeyGen_0_keyMode_f + p_fk_node->fk_prof_id*step, &ds, (1 == p_fk_node->mode)? 1: 0 );
        SetIpfixEngineXCtl(V, gXKeyGen_0_keySel_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->key_sel);
        SetIpfixEngineXCtl(A, gXKeyGen_0_profile_f + p_fk_node->fk_prof_id*step, &ds, fk_profile);

        cmd = DRV_IOW(IpfixEngineXCtl1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

        cmd = DRV_IOR(IpfixEngineXKeyMaskCtl1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_fk_node->fk_mask_id, cmd, &xkey_mask_ctl));
        SetIpfixEngineXKeyMaskCtl(A, data_f, &xkey_mask_ctl, fk_mask);
        cmd = DRV_IOW(IpfixEngineXKeyMaskCtl1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_fk_node->fk_mask_id, cmd, &xkey_mask_ctl));
    }
    break;



    case CTC_XDATA_LOCAL_TYPE_EGS_SCL:
        {
            cmd = DRV_IOR(EgrSclHashXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            step = EgrSclHashXCtl_gXHashkey_1_enable_f - EgrSclHashXCtl_gXHashkey_0_enable_f;
            SetEgrSclHashXCtl(V, gXHashkey_0_enable_f + hash_type*step, &ds, _SYS_FK_SET_V(1));
            SetEgrSclHashXCtl(V, gXHashkey_0_index_f + hash_type*step, &ds, _SYS_FK_SET_V(p_fk_node->fk_prof_id));

            step = EgrSclHashXCtl_gXKeyGen_1_index_f - EgrSclHashXCtl_gXKeyGen_0_index_f;
            SetEgrSclHashXCtl(V, gXKeyGen_0_index_f + p_fk_node->fk_prof_id*step, &ds, p_fk_node->fk_mask_id);
            SetEgrSclHashXCtl(V, gXKeyGen_0_keyMode_f + p_fk_node->fk_prof_id*step, &ds,(1 == p_fk_node->mode)? 1: 0);
            SetEgrSclHashXCtl(V, gXKeyGen_0_keySel_f + p_fk_node->fk_prof_id*step, &ds, _SYS_FK_SET_V(p_fk_node->key_sel));
            SetEgrSclHashXCtl(A, gXKeyGen_0_profile_f + p_fk_node->fk_prof_id*step, &ds, fk_profile);

            step = EgrSclHashXCtl_gXKeyMask_1_data_f - EgrSclHashXCtl_gXKeyMask_0_data_f;
            SetEgrSclHashXCtl(A, gXKeyMask_0_data_f + p_fk_node->fk_mask_id*step, &ds, fk_mask);

            cmd = DRV_IOW(EgrSclHashXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        }
        break;

    default:
        break;
    }

    return 0;
}



int32
sys_usw_xdata_add_fk(uint8 lchip, void* p_para)
{
    sys_xdata_fk_t* p_xdata_fk = (sys_xdata_fk_t*)p_para;
    sys_xdata_fk_db_t fk_db_lkup;
    sys_xdata_fk_db_t* p_fk_node = NULL;
    sys_xdata_fk_f_db_t* pf_db_node = NULL;
    uint8 prof_node = 0;
    sys_usw_opf_t opf;
    int32 ret = CTC_E_NONE;

    sal_memset(&fk_db_lkup, 0, sizeof(fk_db_lkup));
    fk_db_lkup.type = p_xdata_fk->type;
    fk_db_lkup.hash_type = p_xdata_fk->hash_type;
    fk_db_lkup.tbl_id = p_xdata_fk->tbl_id;

    if(SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        return CTC_E_NONE;
    }

    /*1. hash lookup*/
    p_fk_node = ctc_hash_lookup(p_xdata_master[lchip]->fk_hash, &fk_db_lkup);
    if (p_fk_node == NULL)
    {
        p_fk_node = mem_malloc(MEM_XDATA_MODULE, sizeof(sys_xdata_fk_db_t));
        if (!p_fk_node)
        {
            return CTC_E_NO_MEMORY;
        }
        sal_memset(p_fk_node, 0, sizeof(sys_xdata_fk_db_t));
        if (!p_fk_node->p_std_field)
        {
            p_fk_node->p_std_field = mem_malloc(MEM_XDATA_MODULE, sizeof(sys_xdata_std_field_t));
            if (!p_fk_node->p_std_field)
            {
                mem_free(p_fk_node);
                return CTC_E_NO_MEMORY;
            }
            sal_memset(p_fk_node->p_std_field, 0, sizeof(sys_xdata_std_field_t));
        }

        p_fk_node->is_direct_key = p_xdata_fk->direct_index_en;

        p_fk_node->type = p_xdata_fk->type;
        p_fk_node->tbl_id = p_xdata_fk->tbl_id;
        p_fk_node->mode = p_xdata_fk->mode;
        p_fk_node->hash_type = p_xdata_fk->hash_type;
        //p_fk_node->direct_index_en = p_xdata_fk->direct_index_en;
        //p_fk_node->direct_max_index = p_xdata_fk->direct_max_index;
        //p_fk_node->direct_index_mask = p_xdata_fk->direct_index_mask;
        p_fk_node->field_list = ctc_list_new();
        p_fk_node->field_list->cmp = (ctc_list_cmp_cb_t)_sys_usw_xdata_fk_field_cmp;
        p_fk_node->field_list->del = (ctc_list_del_cb_t)_sys_usw_xdata_fk_field_del;

        ctc_hash_insert(p_xdata_master[lchip]->fk_hash, p_fk_node);
    }

    /* installed entry do nothing */
    if (1 == p_fk_node->is_install)
    {
        return CTC_E_ENTRY_EXIST;
    }

    if (p_xdata_fk->info.field != SYS_FK_F_FIELD_DONE)
    {
        CTC_ERROR_RETURN(_sys_usw_xdata_add_fk_field(lchip, p_xdata_fk, &pf_db_node, p_fk_node));

        ctc_listnode_add_sort( p_fk_node->field_list, pf_db_node);
    }
    else
    {
        if (0 == p_fk_node->field_list->count || p_fk_node->is_install)
        {
            return CTC_E_NONE;
        }


        CTC_ERROR_RETURN(_sys_usw_xdata_build_fk(lchip, p_fk_node));

        switch(p_fk_node->type)
        {
            case CTC_XDATA_LOCAL_TYPE_SCL:
                prof_node = SYS_XDATA_FK_PROF_NODE_I_SCL;
                break;
            case SYS_XDATA_LOCAL_TYPE_MAC:
            case SYS_XDATA_LOCAL_TYPE_IP:
                prof_node = SYS_XDATA_FK_PROF_NODE_MAC;
                break;
            case CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT:
            case CTC_XDATA_LOCAL_TYPE_FLOW_HASH:
                prof_node = SYS_XDATA_FK_PROF_NODE_FLOW;
                break;
            case SYS_XDATA_LOCAL_TYPE_XHASH:
                prof_node = SYS_XDATA_FK_PROF_NODE_X_HASH;
                break;
            case CTC_XDATA_LOCAL_TYPE_IPFIX:
                prof_node = SYS_XDATA_FK_PROF_NODE_I_IPFIX;
                break;
            case CTC_XDATA_LOCAL_TYPE_EGS_SCL:
                prof_node = SYS_XDATA_FK_PROF_NODE_E_SCL;
                break;
            case CTC_XDATA_LOCAL_TYPE_EGS_IPFIX:
                prof_node = SYS_XDATA_FK_PROF_NODE_E_IPFIX;
                break;
            default:
                prof_node = SYS_XDATA_FK_PROF_NODE_NUM;
                break;
        }
        if (SYS_XDATA_FK_PROF_NODE_NUM != prof_node)
        {
            uint8 size = 0;
            uint32 value = 0;

            sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
            opf.pool_index = prof_node;
            opf.pool_type  = p_xdata_master[lchip]->opf_type_fk_prof;

            CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, 1, &value))
            p_fk_node->fk_prof_id = value;
            if(!(SYS_XDATA_FK_PROF_NODE_I_SCL == prof_node && 0xff == p_xdata_fk->hash_type))
            {
                size = p_fk_node->key_size + (p_fk_node->mode == SYS_FK_MODE_APPEND ? 1:0);
                opf.pool_type  = p_xdata_master[lchip]->opf_type_fk_mask;
                size = (prof_node == SYS_XDATA_FK_PROF_NODE_I_SCL) ? (1 << size): 1;
                opf.multiple = size;

                CTC_ERROR_GOTO(sys_usw_opf_alloc_offset(lchip, &opf, size, &value),ret,error0);
                p_fk_node->fk_mask_id = value;
            }
        }
        /*
        CTC_LIST_LOOP(p_fk_node->field_list, pf_db_node, node)
        {
            pf_db_node->drv_offset[p_fk_node->fk_prof_id] = pf_db_node->drv_offset;
        }
        */

        /*Write flex key*/
        CTC_ERROR_GOTO(_sys_usw_xdata_install_fk(lchip, p_fk_node, TRUE),ret,error1);

        if (p_fk_node->p_std_field)
        {
            mem_free(p_fk_node->p_std_field);
        }
        p_fk_node->is_install = 1;
        p_xdata_master[lchip]->local[p_fk_node->type].ref_cnt++;
    }
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_FLEX_KEY, 1);

    return ret;
error1:
    if(!(SYS_XDATA_FK_PROF_NODE_I_SCL == prof_node && 0xff == p_xdata_fk->hash_type))
    {
        sys_usw_opf_free_offset(lchip, &opf, 1, (uint32) p_fk_node->fk_mask_id);
    }
error0:
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_index = prof_node;
    opf.pool_type  = p_xdata_master[lchip]->opf_type_fk_prof;
    sys_usw_opf_free_offset(lchip, &opf, 1, (uint32) p_fk_node->fk_prof_id);
    return ret;
}

int32
sys_usw_xdata_remove_fk(uint8 lchip, void* p_para)
{
    sys_xdata_fk_t* p_fk = (sys_xdata_fk_t*)p_para;
    sys_xdata_fk_db_t fk_db_lkup;
    sys_xdata_fk_db_t* p_fk_node = NULL;
    sys_xdata_std_field_t temp_std_field;
    sys_usw_opf_t opf;
    uint8 prof_node = 0;
    uint8 size = 0;

    if(SYS_VCHIP_PP_IS_NOT_BASE(lchip))
    {
        return CTC_E_NONE;
    }

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    sal_memset(&fk_db_lkup, 0, sizeof(fk_db_lkup));
    sal_memset(&temp_std_field, 0, sizeof(sys_xdata_std_field_t));
    fk_db_lkup.type = p_fk->type;
    fk_db_lkup.hash_type = p_fk->hash_type;
    fk_db_lkup.tbl_id = p_fk->tbl_id;

    /*xkey node*/
    p_fk_node = ctc_hash_lookup(p_xdata_master[lchip]->fk_hash, &fk_db_lkup);
    if (!p_fk_node)
    {
        return CTC_E_NOT_EXIST;
    }

    switch(p_fk_node->type)
    {
        case CTC_XDATA_LOCAL_TYPE_SCL:
            prof_node = SYS_XDATA_FK_PROF_NODE_I_SCL;
            break;
        case SYS_XDATA_LOCAL_TYPE_MAC:
        case SYS_XDATA_LOCAL_TYPE_IP:
            prof_node = SYS_XDATA_FK_PROF_NODE_MAC;
            break;
        case CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT:
        case CTC_XDATA_LOCAL_TYPE_FLOW_HASH:
            prof_node = SYS_XDATA_FK_PROF_NODE_FLOW;
            break;
        case SYS_XDATA_LOCAL_TYPE_XHASH:
            prof_node = SYS_XDATA_FK_PROF_NODE_X_HASH;
            break;
        case CTC_XDATA_LOCAL_TYPE_IPFIX:
            prof_node = SYS_XDATA_FK_PROF_NODE_I_IPFIX;
            break;
        case CTC_XDATA_LOCAL_TYPE_EGS_SCL:
            prof_node = SYS_XDATA_FK_PROF_NODE_E_SCL;
            break;
        case CTC_XDATA_LOCAL_TYPE_EGS_IPFIX:
            prof_node = SYS_XDATA_FK_PROF_NODE_E_IPFIX;
            break;
        default:
            prof_node = SYS_XDATA_FK_PROF_NODE_NUM;
            break;
    }

    if (SYS_XDATA_FK_PROF_NODE_NUM != prof_node && p_fk_node->is_install)
    {
        size = p_fk_node->key_size + (p_fk_node->mode == SYS_FK_MODE_APPEND ? 1:0);
        size = prof_node == SYS_XDATA_FK_PROF_NODE_I_SCL? (1<<size): 1 ;
        opf.pool_index = prof_node;
        opf.multiple = size;
        opf.pool_type = p_xdata_master[lchip]->opf_type_fk_mask;
        sys_usw_opf_free_offset(lchip, &opf, size, (uint32) p_fk_node->fk_mask_id);

        opf.multiple = 1;
        opf.pool_type = p_xdata_master[lchip]->opf_type_fk_prof;
        sys_usw_opf_free_offset(lchip, &opf, 1, (uint32) p_fk_node->fk_prof_id);
    }

    if(p_fk_node->is_install)
    {
       p_fk_node->p_std_field = &temp_std_field;
       CTC_ERROR_RETURN(_sys_usw_xdata_install_fk(lchip, p_fk_node, FALSE));
    }
    else
    {
        mem_free(p_fk_node->p_std_field);
    }

    ctc_list_delete(p_fk_node->field_list);
    ctc_hash_remove(p_xdata_master[lchip]->fk_hash, p_fk_node);
    if(1 == p_fk_node->is_install)
    {
        p_xdata_master[lchip]->local[p_fk_node->type].ref_cnt--;
    }
    mem_free(p_fk_node);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_FLEX_KEY, 1);
    return 0;

}


int32
sys_usw_xdata_set_fk_field(uint8 lchip, void* p_para, uint32* p_ds, uint32 value)
{
    sys_xdata_fk_io_t* p_fk = (sys_xdata_fk_io_t*)p_para;
    sys_xdata_fk_db_t fk_db_lkup;
    sys_xdata_fk_db_t* p_fk_node = NULL;

    ctc_listnode_t*   node = NULL;
    ctc_xdata_field_t* p_field = NULL;
    sys_xdata_fk_f_db_t *pf_db_node = NULL;
    sys_xdata_fk_f_db_t *p_field_info = NULL;
    const _sys_xdata_fk_info_t* p_fk_info = NULL;
    uint32 fk_data[CTC_B2W_SIZE(516)];   /*ipfix max field width*/
    uint32 drv_value = value;
    uint8 loop = 0;
    uint8 loop_num = 0;
    uint8 is_add = !!value;

    sal_memset(&fk_db_lkup, 0, sizeof(fk_db_lkup));
    fk_db_lkup.type = p_fk->type;
    fk_db_lkup.hash_type = p_fk->hash_type;
    fk_db_lkup.tbl_id = p_fk->tbl_id;



    /*xkey node*/
    p_fk_node = ctc_hash_lookup(p_xdata_master[lchip]->fk_hash, &fk_db_lkup);
    if (p_fk_node == NULL)
    {
        return CTC_E_NOT_EXIST;
    }

    p_fk_info = sys_usw_xdata_get_fk_info(lchip, p_fk_node);
    if (!p_fk_info)
    {
        return CTC_E_NO_RESOURCE;
    }

    loop_num = (SYS_FK_F_XDATA == p_fk->fk_field && is_add) ? p_fk->xdata->num: 1;

    for(loop = 0;loop < loop_num;loop++)
    {
        if(SYS_FK_F_XDATA == p_fk->fk_field)
        {
            p_field = &p_fk->xdata->fields[loop];
            drv_value = (is_add && value == 1)? p_field->data: value;
        }
        p_field_info = NULL;
        CTC_LIST_LOOP(p_fk_node->field_list, pf_db_node, node)
        {
            if (pf_db_node->field != p_fk->fk_field ||(p_fk->fk_field == SYS_FK_F_XDATA && is_add &&
                (pf_db_node->width != p_field->width || pf_db_node->pos_sel != p_field->offset/CTC_XDATA_WIDTH_4)))
            {
                continue;
            }
            p_field_info = pf_db_node;
            DRV_GET_FIELD_A(lchip,p_fk_info->tbl_id,p_fk_info->fld_id,p_ds,fk_data);
            drv_value = drv_value & pf_db_node->mask;
            CTC_BMP_COPY_RANGE(fk_data, p_field_info->drv_offset, &drv_value, 0, p_field_info->bit_width);
            DRV_SET_FIELD_A(lchip,p_fk_info->tbl_id,p_fk_info->fld_id,p_ds,fk_data);
        }
        if (NULL == p_field_info)
        {
            return CTC_E_NOT_EXIST;
        }
    }

    return 0;
}

int32
sys_usw_xdata_get_fk_field(uint8 lchip, void* p_para, uint32* p_ds, uint32* value)
{
    sys_xdata_fk_io_t* p_fk = (sys_xdata_fk_io_t*)p_para;
    sys_xdata_fk_db_t fk_db_lkup;
    sys_xdata_fk_db_t* p_fk_node = NULL;

    ctc_listnode_t*   node = NULL;
    ctc_xdata_field_t* p_field = NULL;
    sys_xdata_fk_f_db_t *pf_db_node = NULL;
    sys_xdata_fk_f_db_t *p_field_info = NULL;
    const _sys_xdata_fk_info_t* p_fk_info = NULL;
    uint32 fk_data[CTC_B2W_SIZE(516)];   /*ipfix max field width*/
    uint8 loop_num = 0;

    sal_memset(&fk_db_lkup, 0, sizeof(fk_db_lkup));
    fk_db_lkup.type = p_fk->type;
    fk_db_lkup.hash_type = p_fk->hash_type;
    fk_db_lkup.tbl_id = p_fk->tbl_id;

    /*xkey node*/
    p_fk_node = ctc_hash_lookup(p_xdata_master[lchip]->fk_hash, &fk_db_lkup);
    if (p_fk_node == NULL)
    {
        return CTC_E_NOT_EXIST;
    }

    p_fk_info = sys_usw_xdata_get_fk_info(lchip, p_fk_node);
    if (!p_fk_info)
    {
        return CTC_E_NO_RESOURCE;
    }


    CTC_LIST_LOOP(p_fk_node->field_list, pf_db_node, node)
    {
        if (pf_db_node->field != p_fk->fk_field)
        {
            continue;
        }
        p_field_info = pf_db_node;
        DRV_GET_FIELD_A(lchip,p_fk_info->tbl_id,p_fk_info->fld_id,p_ds,fk_data);
        CTC_BMP_COPY_RANGE( value, 0, fk_data, p_field_info->drv_offset, p_field_info->bit_width);
        if(SYS_FK_F_XDATA == p_fk->fk_field)
        {
            p_field = &p_fk->xdata->fields[loop_num];
            p_field->width = p_field_info->width;
            p_field->offset = p_field_info->pos_sel*CTC_XDATA_WIDTH_4;
            p_field->data = *value;
            loop_num++;
            p_fk->xdata->num = loop_num;
            p_fk->xdata->type = p_fk_node->type;
        }
    }

    if (NULL == p_field_info)
    {
        return CTC_E_NOT_EXIST;
    }

    return 0;

}


int32
_sys_usw_xdata_free_vec_node_data(void* node_data, void* user_data)
{
    mem_free(node_data);
    return CTC_E_NONE;
}

int32
_sys_usw_xdata_free_fk_node_data(void* node_data, void* user_data)
{
    sys_xdata_fk_db_t* p_node = node_data;
    if (p_node)
    {
        ctc_list_delete(p_node->field_list);
        mem_free(p_node);
    }
    return CTC_E_NONE;
}


int32
sys_usw_xdata_deinit(uint8 lchip)
{
    SYS_VCHIP_MASTER_DEINIT(lchip, p_xdata_master, CTC_FEATURE_XDATA);

    if (!p_xdata_master[lchip])
    {
        return CTC_E_NONE;
    }
    sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_XDATA, NULL);

    /* free opf */
    sys_usw_opf_deinit(lchip, p_xdata_master[lchip]->opf_type_fk_prof);
    sys_usw_opf_deinit(lchip, p_xdata_master[lchip]->opf_type_fk_mask);

    ctc_hash_free2(p_xdata_master[lchip]->fk_hash, (hash_traversal_fn)_sys_usw_xdata_free_fk_node_data, NULL);
    ctc_vector_traverse(p_xdata_master[lchip]->prof_vec, (vector_traversal_fn)_sys_usw_xdata_free_vec_node_data, NULL);
    ctc_vector_release(p_xdata_master[lchip]->prof_vec);
    ctc_vector_traverse(p_xdata_master[lchip]->path_vec, (vector_traversal_fn)_sys_usw_xdata_free_vec_node_data, NULL);
    ctc_vector_release(p_xdata_master[lchip]->path_vec);

    sys_usw_xdata_local_kset_deint(lchip);
    sal_mutex_destroy(p_xdata_master[lchip]->mutex);
    mem_free(p_xdata_master[lchip]);

    return CTC_E_NONE;
}


STATIC uint32
_sys_xdata_fk_hash_make(sys_xdata_fk_db_t* node)
{
    return ctc_hash_caculate(2*sizeof(uint32), node);
}

STATIC bool
_sys_xdata_fk_hash_cmp(sys_xdata_fk_db_t* stored_node, sys_xdata_fk_db_t* lkup_node)
{
    if (!stored_node || !lkup_node)
    {
        return TRUE;
    }

    if ((stored_node->type == lkup_node->type)
        && (stored_node->tbl_id == lkup_node->tbl_id)
        && (stored_node->hash_type == lkup_node->hash_type))
    {
        return TRUE;
    }

    return FALSE;
}

#define SYS_FK_F_INFO_INIT(F_TYPE,SRC_POS,WIDTH,OFFSET,BIT_WIDTH,SHARE_FIELD)\
{\
    p_xdata_master[lchip]->fk_f_info[loop][F_TYPE].src_pos = SRC_POS;\
    p_xdata_master[lchip]->fk_f_info[loop][F_TYPE].width = WIDTH;\
    p_xdata_master[lchip]->fk_f_info[loop][F_TYPE].offset = OFFSET;\
    p_xdata_master[lchip]->fk_f_info[loop][F_TYPE].bit_width = BIT_WIDTH;\
    p_xdata_master[lchip]->fk_f_info[loop][F_TYPE].share_field = SHARE_FIELD;\
}

int32
_sys_usw_xdata_fk_f_info_init(uint8 lchip)
{
    uint8 loop = 0;

    for(loop = CTC_XDATA_LOCAL_TYPE_SCL; loop < SYS_XDATA_LOCAL_TYPE_MAX; loop++)
    {
        switch(loop)
        {
            case CTC_XDATA_LOCAL_TYPE_SCL:
                /* 4 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_EXT_TYPE, 0, 4, 0, 4, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_L4_USER_TYPE, 1, 4, 0, 4, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_L4_TYPE, 2, 4, 0, 4, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_L2_TYPE, 3, 4, 0, 3, SYS_FK_F_XDATA_NIBBLE3);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_IP_HDR_ERROR, 3, 4, 3, 1, SYS_FK_F_XDATA_NIBBLE3);
                /* 8 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_EXT_DATA0, 0, 8, 0, 8, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_EXT_DATA1, 1, 8, 0, 8, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_EXT_DATA2, 2, 8, 0, 8, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_EXT_DATA3, 3, 8, 0, 8, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_VNI0, 4, 8, 0, 8, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_FRAG_INFO, 5, 8, 0, 2, SYS_FK_F_XDATA_BYTE5);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_VLAN_NUM, 5, 8, 2, 2, SYS_FK_F_XDATA_BYTE5);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_L3_TYPE, 5, 8, 4, 4, SYS_FK_F_XDATA_BYTE5);
                /* 16 bit*/
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_VNI0, 0, 16, 0, 16, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_EXT_DATA4, 1, 16, 0, 16, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_EXT_DATA5, 2, 16, 0, 16, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_VLAN_RANGE_MAX_LO, 3, 16, 0, 8, SYS_FK_F_XDATA_WORD3);
                SYS_FK_F_INFO_INIT(SYS_FK_F_VLAN_RANGE_MAX_HI, 3, 16, 8, 4, SYS_FK_F_XDATA_WORD3);
                SYS_FK_F_INFO_INIT(SYS_FK_F_VLAN_RANGE_VALID, 3, 16, 12, 1, SYS_FK_F_XDATA_WORD3);
                SYS_FK_F_INFO_INIT(SYS_FK_F_VLAN_RANGE_TYPE, 3, 16, 13, 1, SYS_FK_F_XDATA_WORD3);
            break;
            case CTC_XDATA_LOCAL_TYPE_EGS_SCL:
                /* 4 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_PKT_FWD_TYPE, 1, 4, 0, 4, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_EXT_TYPE, 3, 4, 0, 4, 0);
                /* 8 bit */
                //SYS_FK_F_INFO_INIT(SYS_XDATA_PR_EXT_DATA0, 0, 8, 0, 8, 0);
                /* 16 bit*/
                SYS_FK_F_INFO_INIT(SYS_FK_F_DST_CID, 0, 16, 0, 16, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_LP_GRP, 2, 16, 0, 16, 0);
            break;
            case CTC_XDATA_LOCAL_TYPE_FLOW_HASH:

                /* 4 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_L3_TYPE, 0, 4, 0, 4, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_L4_TYPE, 1, 4, 0, 4, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_L4_USER_TYPE, 2, 4, 0, 4, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_FRAG_INFO, 3, 4, 0, 2, SYS_FK_F_XDATA_NIBBLE3);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_VLAN_NUM, 3, 4, 2, 2, SYS_FK_F_XDATA_NIBBLE3);

                /* 8 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_IS_DECAP, 0, 8, 5, 1, SYS_FK_F_XDATA_BYTE0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_IP_HDR_ERROR, 1, 8, 7, 1, SYS_FK_F_XDATA_BYTE1);
                SYS_FK_F_INFO_INIT(SYS_FK_F_DISCARD, 1, 8, 6, 1, SYS_FK_F_XDATA_BYTE1);
                SYS_FK_F_INFO_INIT(SYS_FK_F_DISCARD_TYPE, 1, 8, 0, 6, SYS_FK_F_XDATA_BYTE1);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_L2_TYPE, 2, 8, 4, 3, SYS_FK_F_XDATA_BYTE2);
                SYS_FK_F_INFO_INIT(SYS_FK_F_STP_STATE, 2, 8, 2, 2, SYS_FK_F_XDATA_BYTE2);
                SYS_FK_F_INFO_INIT(SYS_FK_F_CVLAN_ID_VALID, 2, 8, 1, 1, SYS_FK_F_XDATA_BYTE2);
                SYS_FK_F_INFO_INIT(SYS_FK_F_SVLAN_ID_VALID, 2, 8, 0, 1, SYS_FK_F_XDATA_BYTE2);
                SYS_FK_F_INFO_INIT(SYS_FK_F_CVLAN_ID_LO, 3, 8, 0, 8, SYS_FK_F_XDATA_BYTE3);
                SYS_FK_F_INFO_INIT(SYS_FK_F_SVLAN_ID_LO, 4, 8, 0, 8, SYS_FK_F_XDATA_BYTE4);
                SYS_FK_F_INFO_INIT(SYS_FK_F_CVLAN_ID_HI, 5, 8, 4, 4, SYS_FK_F_XDATA_BYTE5);
                SYS_FK_F_INFO_INIT(SYS_FK_F_SVLAN_ID_HI, 5, 8, 0, 4, SYS_FK_F_XDATA_BYTE5);

                /* 16 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_L3_IF_ID, 0, 16, 0, 16, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_LOGIC_SRC_PORT, 1, 16, 0, 16, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_FID, 2, 16, 0, 16, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_VRF_ID, 3, 16, 0, 16, 0);

            break;
            case CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT:
                /* 4 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_VALID, 0, 4, 0, 4, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_HI_VALID, 2, 4, 0, 4, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_HIT_INDEX, 1, 4, 0, 4, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_HI_HIT_INDEX, 3, 4, 0, 4, 0);

                /* 8 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_HI_DATA4, 0, 8, 0, 8, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_DATA4, 1, 8, 0, 8, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_HI_DATA5, 2, 8, 0, 8, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_DATA5, 3, 8, 0, 8, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_HI_DATA6, 4, 8, 0, 8, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_DATA7, 5, 8, 0, 8, 0);

                /* 16 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_DATA0, 0, 16, 0, 16, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_DATA1, 1, 16, 0, 16, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_DATA2, 2, 16, 0, 16, 0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_UDF_DATA3, 3, 16, 0, 16, 0);

            break;
            case CTC_XDATA_LOCAL_TYPE_IPFIX:
                /* 8 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_DISCARD_TYPE, 0, 8, 0, 6, SYS_FK_F_XDATA_BYTE0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_DISCARD, 0, 8, 6, 1, SYS_FK_F_XDATA_BYTE0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_IP_TTL, 1, 8, 0, 8, 0);
            break;
            case CTC_XDATA_LOCAL_TYPE_EGS_IPFIX:
                /* 4 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_PRIORITY, 2, 4, 0, 4, 0);
                /* 8 bit */
                SYS_FK_F_INFO_INIT(SYS_FK_F_DISCARD_TYPE, 0, 8, 0, 6, SYS_FK_F_XDATA_BYTE0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_DISCARD, 0, 8, 6, 1, SYS_FK_F_XDATA_BYTE0);
                SYS_FK_F_INFO_INIT(SYS_FK_F_PR_IP_TTL, 1, 8, 0, 8, 0);
                /* 16 bit*/
                SYS_FK_F_INFO_INIT(SYS_FK_F_SRC_GPORT, 3, 16, 0, 16, 0);
            break;
            default:
            break;

        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_xdata_global_init(uint8 lchip)
{
    uint32 cmd = 0;
    ds1_t   ds;
    uint8 step = 0;
    uint8 loop = 0;

    /* CTC_XDATA_PATH_TYPE_IPE_BSR/CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR */
    cmd = DRV_IOR(IpeFwdXCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetIpeFwdXCtl(V,xPHTypeEn_f,&ds,1);
    SetIpeFwdXCtl(V,xPHTypeSel_f,&ds,31);
    SetIpeFwdXCtl(V,xPHExtTypeEn_f,&ds,1);
    SetIpeFwdXCtl(V,xPHExtTypeSel_f,&ds,30);
    step = IpeFwdXCtl_gXHeader_1_xType_f - IpeFwdXCtl_gXHeader_0_xType_f;
    loop = 0;
    do{
        SetIpeFwdXCtl(V, gXHeader_0_xType_f + step*loop, ds, loop);
    }while(++loop < 8);
    cmd = DRV_IOW(IpeFwdXCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));


    /* CTC_XDATA_PATH_TYPE_EPE_LOOP0/CTC_XDATA_PATH_TYPE_EPE_LOOP1 */
    cmd = DRV_IOR(EpeHeaderEditXCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    SetEpeHeaderEditXCtl(V,xPHTypeEn_f,&ds,1);
    SetEpeHeaderEditXCtl(V,xPHTypeSel_f,&ds,31);
    SetEpeHeaderEditXCtl(V,xPHExtTypeEn_f,&ds,1);
    SetEpeHeaderEditXCtl(V,xPHExtTypeSel_f,&ds,30);
    step = EpeHeaderEditXCtl_gXHeader_1_xType_f - EpeHeaderEditXCtl_gXHeader_0_xType_f;
    loop = 0;
    do{
        SetEpeHeaderEditXCtl(V, gXHeader_0_xType_f + step*loop, ds, loop);
    }while(++loop < 4);
    cmd = DRV_IOW(EpeHeaderEditXCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    return CTC_E_NONE;
}

#define SYS_XDATA_PROF_NUM  45
#define SYS_XDATA_LOCAL_NUM  6
#define SYS_XDATA_PATH_NUM  32
#define SYS_XDATA_FK_NUM  128

int32
_sys_usw_xdata_prof_wb_mapping(uint8 lchip, sys_wb_xdata_profile_t* p_wb_xdata_prof, sys_xdata_prof_info_t* p_xdata_prof, uint32 vec_index, uint8 sync)
{
    if (sync)
    {
        p_wb_xdata_prof->idx = vec_index;
        p_wb_xdata_prof->num = p_xdata_prof->num;
        sal_memcpy(p_wb_xdata_prof->map, p_xdata_prof->field, p_xdata_prof->num*sizeof(sys_xdata_prof_field_t));
    }
    else
    {
        uint8 type = 0;
        uint8 prof_id = 0;
        p_xdata_prof->num = p_wb_xdata_prof->num;
        sal_memcpy(p_xdata_prof->field, p_wb_xdata_prof->map,p_wb_xdata_prof->num*sizeof(sys_xdata_prof_field_t));
        if(FALSE == ctc_vector_add(p_xdata_master[lchip]->prof_vec,  p_wb_xdata_prof->idx,(void*)p_xdata_prof))
        {
            return CTC_E_NO_MEMORY;
        }
        type = p_wb_xdata_prof->idx >> 3;
        prof_id = p_wb_xdata_prof->idx & 0x7;
        CTC_BIT_SET(p_xdata_master[lchip]->prof_bmp[type], prof_id);
    }
    return CTC_E_NONE;
}

int32
_sys_usw_xdata_path_wb_mapping(uint8 lchip, sys_wb_xdata_path_t* p_wb_xdata_path, sys_xdata_path_info_t* p_xdata_path, uint32 vec_index, uint8 sync)
{
    if (sync)
    {
        p_wb_xdata_path->idx = vec_index;
        p_wb_xdata_path->num = p_xdata_path->num;
        p_wb_xdata_path->fixed_bmp = p_xdata_path->fixed_bmp;
        p_wb_xdata_path->valid_bmp = p_xdata_path->valid_bmp;
        sal_memcpy(p_wb_xdata_path->map, p_xdata_path->field, p_xdata_path->num*sizeof(sys_xdata_path_field_t));
    }
    else
    {
        uint8 type = 0;
        uint8 prof_id = 0;
        p_xdata_path->num = p_wb_xdata_path->num;
        p_xdata_path->fixed_bmp = p_wb_xdata_path->fixed_bmp;
        p_xdata_path->valid_bmp = p_wb_xdata_path->valid_bmp;
        sal_memcpy(p_xdata_path->field, p_wb_xdata_path->map,p_wb_xdata_path->num*sizeof(sys_xdata_path_field_t));
        if(FALSE == ctc_vector_add(p_xdata_master[lchip]->path_vec, p_wb_xdata_path->idx, (void*)p_xdata_path))
        {
            return CTC_E_NO_MEMORY;
        }
        type = p_wb_xdata_path->idx >> 3;
        prof_id = p_wb_xdata_path->idx & 0x7;
        CTC_BIT_SET(p_xdata_master[lchip]->path_bmp[type], prof_id);
        if(CTC_XDATA_PATH_TYPE_BSR_EPE == type && CTC_FLAG_ISSET(p_xdata_path->fixed_bmp , CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT))
        {
            CTC_BIT_SET(p_xdata_master[lchip]->logic_port_ext_bmp, prof_id);
        }
    }
    return CTC_E_NONE;
}


uint32
_sys_usw_xdata_unmap_fk_field(int32 fk_field)
{
    uint32 ctc_field = 0;
    switch(fk_field)
    {
        case SYS_FK_F_PR_L3_TYPE:
            ctc_field = CTC_FIELD_KEY_L3_TYPE;
            break;
        case SYS_FK_F_PR_L4_TYPE:
            ctc_field = CTC_FIELD_KEY_L4_TYPE;
            break;
        case SYS_FK_F_PR_L4_USER_TYPE:
            ctc_field = CTC_FIELD_KEY_L4_USER_TYPE;            
            break;
        case SYS_FK_F_PR_VLAN_NUM:
            ctc_field =  CTC_FIELD_KEY_VLAN_NUM;            
            break;
        case SYS_FK_F_PR_FRAG_INFO:
            ctc_field = CTC_FIELD_KEY_IP_FRAG;            
            break;
        case SYS_FK_F_IS_DECAP:
            ctc_field = CTC_FIELD_KEY_DECAP;            
            break;
        case SYS_FK_F_PR_IP_HDR_ERROR:
            ctc_field = CTC_FIELD_KEY_IP_HDR_ERROR;            
            break;
        case SYS_FK_F_DISCARD:
        case SYS_FK_F_DISCARD_TYPE:
            ctc_field = CTC_FIELD_KEY_DISCARD ;
            break;
        case SYS_FK_F_PR_L2_TYPE:
            ctc_field = CTC_FIELD_KEY_L2_TYPE;            
            break;
        case SYS_FK_F_STP_STATE :
            ctc_field = CTC_FIELD_KEY_STP_STATE;            
            break;
        case SYS_FK_F_CVLAN_ID_VALID :
            ctc_field = CTC_FIELD_KEY_CTAG_VALID;            
            break;
        case SYS_FK_F_SVLAN_ID_VALID:
            ctc_field =  CTC_FIELD_KEY_STAG_VALID ;
            break;
        case SYS_FK_F_SVLAN_ID_LO :
        case SYS_FK_F_SVLAN_ID_HI :
            ctc_field = CTC_FIELD_KEY_SVLAN_ID;
            break;
        case SYS_FK_F_CVLAN_ID_LO :
        case SYS_FK_F_CVLAN_ID_HI :
            ctc_field = CTC_FIELD_KEY_CVLAN_ID;
            break;
        case SYS_FK_F_L3_IF_ID :
            ctc_field = CTC_FIELD_KEY_INTERFACE_ID;            
            break;
        case SYS_FK_F_LOGIC_SRC_PORT :
            ctc_field = CTC_FIELD_KEY_LOGIC_SRC_PORT;            
            break;
        case SYS_FK_F_FID :
            ctc_field = CTC_FIELD_KEY_FID;            
            break;
        case  SYS_FK_F_VRF_ID :
            ctc_field = CTC_FIELD_KEY_VRFID;            
            break;
        case  SYS_FK_F_XDATA :
            ctc_field  = CTC_FIELD_KEY_XDATA;
            break;
        case SYS_FK_F_SRC_GPORT :
            ctc_field  = CTC_FIELD_KEY_SRC_GPORT;
            break;
        case SYS_FK_F_PR_IP_TTL :
            ctc_field = CTC_FIELD_KEY_IP_TTL;
            break;
        case SYS_FK_F_PRIORITY :
            ctc_field = CTC_FIELD_KEY_PRIORITY;
            break;
        case SYS_FK_F_VLAN_RANGE_MAX_LO:
        case SYS_FK_F_VLAN_RANGE_MAX_HI:
        case SYS_FK_F_VLAN_RANGE_VALID:
        case SYS_FK_F_VLAN_RANGE_TYPE:
        //case CTC_FIELD_KEY_CVLAN_RANGE:
            ctc_field = CTC_FIELD_KEY_SVLAN_RANGE;
            break;
        case SYS_FK_F_UDF_DATA0 :
        case SYS_FK_F_UDF_DATA1 :
        case SYS_FK_F_UDF_DATA2 :
        case SYS_FK_F_UDF_DATA3 :
        case SYS_FK_F_UDF_DATA4 :
        case SYS_FK_F_UDF_DATA5 :
        case SYS_FK_F_UDF_DATA6 :
        case SYS_FK_F_UDF_DATA7 :
        case SYS_FK_F_UDF_HI_DATA0 :
        case SYS_FK_F_UDF_HI_DATA1 :
        case SYS_FK_F_UDF_HI_DATA2 :
        case SYS_FK_F_UDF_HI_DATA3 :
        case SYS_FK_F_UDF_HI_DATA4 :
        case SYS_FK_F_UDF_HI_DATA5 :
        case SYS_FK_F_UDF_HI_DATA6 :
        case SYS_FK_F_UDF_HI_DATA7 :
        case SYS_FK_F_UDF_HIT_INDEX_LO : 
        case SYS_FK_F_UDF_HIT_INDEX:
            ctc_field = CTC_FIELD_KEY_UDF;
            break;
        case SYS_FK_F_PKT_FWD_TYPE :
            ctc_field = CTC_FIELD_KEY_PKT_FWD_TYPE;            
            break;
        case SYS_FK_F_DST_CID :
            ctc_field = CTC_FIELD_KEY_DST_CID ;            
            break;
        default:
            ctc_field = CTC_FIELD_KEY_NUM;
    }
    return ctc_field;
}


int32
_sys_usw_xdata_fk_wb_mapping(uint8 lchip, sys_wb_xdata_flex_key_t* p_wb_xdata_fk, sys_xdata_fk_db_t* p_xdata_fk, uint8 sync)
{
    int32 ret = CTC_E_NONE;
    sys_xdata_fk_f_db_t *pf_db_node = NULL;

    if (sync)
    {
        uint8 num = 0;
        uint8 i = 0;
        ctc_listnode_t*   node = NULL;
        sys_wb_xdata_flex_key_f_t* p_fk_field = NULL;


        p_wb_xdata_fk->tbl_id = p_xdata_fk->tbl_id;
        p_wb_xdata_fk->hash_type = p_xdata_fk->hash_type;
        p_wb_xdata_fk->type = p_xdata_fk->type;
        p_wb_xdata_fk->mode  = p_xdata_fk->mode;
        p_wb_xdata_fk->fk_prof_id = p_xdata_fk->fk_prof_id;
        p_wb_xdata_fk->fk_mask_id = p_xdata_fk->fk_mask_id;
        p_wb_xdata_fk->key_size = p_xdata_fk->key_size;
        p_wb_xdata_fk->is_install = p_xdata_fk->is_install;
        p_wb_xdata_fk->udf_en = p_xdata_fk->udf_en;
        p_wb_xdata_fk->key_sel = p_xdata_fk->key_sel;

        num = p_xdata_fk->field_list->count;
        CTC_LIST_LOOP(p_xdata_fk->field_list, pf_db_node, node)
        {
            p_fk_field = &p_wb_xdata_fk->fk_field[i++];
            p_fk_field->field = pf_db_node->field;
            p_fk_field->bit_width = pf_db_node->bit_width;
            p_fk_field->pos_sel = pf_db_node->pos_sel;
            p_fk_field->mask = pf_db_node->mask;
            p_fk_field->width = pf_db_node->width;
            p_fk_field->drv_offset = pf_db_node->drv_offset;
            p_fk_field->father_field = pf_db_node->father_field;
            p_fk_field->start_bit = pf_db_node->start_bit;
            p_fk_field->is_done = (num == i)? 1: 0;
        }
    }
    else
    {
        uint8 loop = 0;
        sys_wb_xdata_flex_key_f_t* p_wb_field = NULL;
        uint8 fk_prof_node = 0;
        sys_usw_opf_t opf;
        uint8 size = 0;

        sal_memset(&opf, 0, sizeof(sys_usw_opf_t));

        /* create field list */
        p_xdata_fk->field_list = ctc_list_new();
        p_xdata_fk->field_list->cmp = (ctc_list_cmp_cb_t)_sys_usw_xdata_fk_field_cmp;
        p_xdata_fk->field_list->del = (ctc_list_del_cb_t)_sys_usw_xdata_fk_field_del;

        p_xdata_fk->tbl_id = p_wb_xdata_fk->tbl_id;
        p_xdata_fk->hash_type = p_wb_xdata_fk->hash_type;
        p_xdata_fk->type = p_wb_xdata_fk->type;
        p_xdata_fk->mode  = p_wb_xdata_fk->mode;
        p_xdata_fk->fk_prof_id = p_wb_xdata_fk->fk_prof_id;
        p_xdata_fk->fk_mask_id = p_wb_xdata_fk->fk_mask_id;
        p_xdata_fk->key_size = p_wb_xdata_fk->key_size;
        p_xdata_fk->is_install = p_wb_xdata_fk->is_install;
        p_xdata_fk->udf_en = p_wb_xdata_fk->udf_en;
        p_xdata_fk->key_sel = p_wb_xdata_fk->key_sel;

        for(loop = 0; loop < SYS_WB_XDATA_FK_F_NUM; loop++)
        {
            p_wb_field = &p_wb_xdata_fk->fk_field[loop];
            pf_db_node = mem_malloc(MEM_XDATA_MODULE, sizeof(sys_xdata_fk_f_db_t));
            if (!pf_db_node)
            {
                ret =  CTC_E_NO_MEMORY;
                goto error0;
            }
            pf_db_node->field = p_wb_field->field;
            pf_db_node->bit_width = p_wb_field->bit_width;
            pf_db_node->pos_sel = p_wb_field->pos_sel;
            pf_db_node->mask = p_wb_field->mask;
            pf_db_node->width = p_wb_field->width;
            pf_db_node->drv_offset = p_wb_field->drv_offset;
            pf_db_node->father_field = p_wb_field->father_field;
            pf_db_node->start_bit = p_wb_field->start_bit;
            pf_db_node->ptr_field_name = ifp_field_str[_sys_usw_xdata_unmap_fk_field(pf_db_node->field)];
            ctc_listnode_add_sort( p_xdata_fk->field_list, pf_db_node);
            if(p_wb_field->is_done)
            {
                break;
            }
        }

        switch(p_wb_xdata_fk->type)
        {
            case CTC_XDATA_LOCAL_TYPE_SCL:
                fk_prof_node = SYS_XDATA_FK_PROF_NODE_I_SCL;
                break;
            case CTC_XDATA_LOCAL_TYPE_EGS_SCL:
                fk_prof_node = SYS_XDATA_FK_PROF_NODE_E_SCL;
                break;
            case CTC_XDATA_LOCAL_TYPE_FLOW_HASH:
            case CTC_XDATA_LOCAL_TYPE_FLOW_HASH_EXT:
                fk_prof_node = SYS_XDATA_FK_PROF_NODE_FLOW;
                break;
            case SYS_XDATA_LOCAL_TYPE_XHASH:
                fk_prof_node = SYS_XDATA_FK_PROF_NODE_X_HASH;
                break;
            case CTC_XDATA_LOCAL_TYPE_IPFIX:
                fk_prof_node = SYS_XDATA_FK_PROF_NODE_I_IPFIX;
                break;
            case CTC_XDATA_LOCAL_TYPE_EGS_IPFIX:
                fk_prof_node = SYS_XDATA_FK_PROF_NODE_E_IPFIX;
                break;
            default:
                return CTC_E_INVALID_PARAM;
        }

        opf.pool_index = fk_prof_node;
        opf.pool_type  = p_xdata_master[lchip]->opf_type_fk_prof;
        sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, p_wb_xdata_fk->fk_prof_id);

        /* keep end */
        if(fk_prof_node == SYS_XDATA_FK_PROF_NODE_X_HASH || (fk_prof_node == SYS_XDATA_FK_PROF_NODE_I_SCL && 0xff == p_xdata_fk->hash_type))
        {
            return CTC_E_NONE;
        }

        size = p_wb_xdata_fk->key_size + (p_xdata_fk->mode == SYS_FK_MODE_APPEND ? 1:0);
        size = (fk_prof_node == SYS_XDATA_FK_PROF_NODE_I_SCL) ? (1 << size) : 1; 
        opf.pool_index = fk_prof_node;
        opf.pool_type  = p_xdata_master[lchip]->opf_type_fk_mask;
        opf.multiple = size;
        sys_usw_opf_alloc_offset_from_position(lchip, &opf, size, p_wb_xdata_fk->fk_mask_id);
    }
    return CTC_E_NONE;
error0:
    ctc_list_delete(p_xdata_fk->field_list);
    return ret;
}


int32
_sys_usw_xdata_wb_sync_prof_func(void* node_data, uint32 vec_index, void* user_data)
{
    uint32 max_entry_cnt = 0;
    ctc_wb_data_t* p_wb_data = (ctc_wb_data_t*) user_data;
    sys_wb_xdata_profile_t* p_wb_xdata_prof = NULL;
    sys_xdata_prof_info_t* p_xdata_prof = (sys_xdata_prof_info_t*)node_data;

    max_entry_cnt = p_wb_data->buffer_len/ sizeof(sys_wb_xdata_profile_t);
    p_wb_xdata_prof = (sys_wb_xdata_profile_t*) p_wb_data->buffer + p_wb_data->valid_cnt;
    CTC_ERROR_RETURN(_sys_usw_xdata_prof_wb_mapping(0, p_wb_xdata_prof, p_xdata_prof, vec_index, 1));
    if (++p_wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_xdata_wb_sync_path_func(void* node_data, uint32 vec_index, void* user_data)
{
    uint32 max_entry_cnt = 0;
    ctc_wb_data_t* p_wb_data = (ctc_wb_data_t*) user_data;
    sys_wb_xdata_path_t* p_wb_xdata_path = NULL;
    sys_xdata_path_info_t* p_xdata_path = (sys_xdata_path_info_t*)node_data;

    max_entry_cnt = p_wb_data->buffer_len/ sizeof(sys_wb_xdata_path_t);
    p_wb_xdata_path = (sys_wb_xdata_path_t*) p_wb_data->buffer + p_wb_data->valid_cnt;
    CTC_ERROR_RETURN(_sys_usw_xdata_path_wb_mapping(0, p_wb_xdata_path, p_xdata_path, vec_index, 1));
    if (++p_wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_xdata_wb_sync_fk_func(void* node_data, void* user_data)
{
    uint32 max_entry_cnt = 0;
    uint8 lchip = (((sys_traverse_t*)user_data)->value1);
    ctc_wb_data_t* p_wb_data = (ctc_wb_data_t*)(((sys_traverse_t*)user_data)->data);
    sys_wb_xdata_flex_key_t* p_wb_xdata_fk = NULL;
    sys_xdata_fk_db_t* p_xdata_fk = (sys_xdata_fk_db_t*)node_data;

    max_entry_cnt = p_wb_data->buffer_len/ sizeof(sys_wb_xdata_flex_key_t);
    p_wb_xdata_fk = (sys_wb_xdata_flex_key_t*) p_wb_data->buffer + p_wb_data->valid_cnt;
    CTC_ERROR_RETURN(_sys_usw_xdata_fk_wb_mapping(lchip,p_wb_xdata_fk, p_xdata_fk, 1));
    if (++p_wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(p_wb_data));
        p_wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}


int32
sys_usw_xdata_wb_sync(uint8 lchip, uint32 app_id)
{
    int32  ret       = CTC_E_NONE;
    uint8 loop = 0;
    uint8 loop1 = 0;
    ctc_wb_data_t wb_data = {0};
    sys_wb_xdata_master_t* p_wb_xdata_master = NULL;
    sys_xdata_local_t* p_xdata_local = NULL;
    sys_wb_xdata_local_t* p_wb_xdata_local = NULL;
    sys_traverse_t user_data;

    CTC_WB_ALLOC_BUFFER(&wb_data.buffer);
    SYS_XDATA_LOCK(lchip);
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_XDATA_SUBID_MASTER)
    {
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_xdata_master_t, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_MASTER);
        p_wb_xdata_master = (sys_wb_xdata_master_t*)wb_data.buffer;
        p_wb_xdata_master->lchip = lchip;
        p_wb_xdata_master->version = SYS_WB_VERSION_XDATA;

        for(loop = 0; loop < CTC_XDATA_LOCAL_TYPE_MAX; loop++)
        {
            p_xdata_local = &p_xdata_master[lchip]->local[loop];
            p_wb_xdata_local = &p_wb_xdata_master->local[loop];
            p_wb_xdata_local->mode = p_xdata_local->mode;
            p_wb_xdata_local->num = p_xdata_local->num;
            p_wb_xdata_local->type = p_xdata_local->type;
            p_wb_xdata_local->ref_cnt = p_xdata_local->ref_cnt;
            for(loop1 = 0; loop1 < SYS_XDATA_LOCAL_FIELD_MAX; loop1++)
            {
                sal_memcpy(&p_wb_xdata_local->field[loop1], &p_xdata_local->field[loop1],sizeof(sys_xdata_local_field_t));
            }
        }

        wb_data.valid_cnt = 1;
        CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
        wb_data.valid_cnt = 0;
        CTC_WB_SYNC_END_DATA( CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_MASTER);
    }

    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_XDATA_SUBID_PROF)
    {
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_xdata_profile_t, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PROF);

        CTC_ERROR_GOTO(ctc_vector_traverse2(p_xdata_master[lchip]->prof_vec, 0, _sys_usw_xdata_wb_sync_prof_func, (void*)(&wb_data)), ret, done);

        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
        }
        CTC_WB_SYNC_END_DATA( CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PROF);
    }

    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_XDATA_SUBID_PATH)
    {
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_xdata_path_t, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PATH);

        CTC_ERROR_GOTO(ctc_vector_traverse2(p_xdata_master[lchip]->path_vec, 0, _sys_usw_xdata_wb_sync_path_func, (void*)(&wb_data)), ret, done);

        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
        }
        CTC_WB_SYNC_END_DATA( CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PATH);
    }

    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_XDATA_SUBID_FLEX_KEY)
    {
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_xdata_flex_key_t, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_FLEX_KEY);
        user_data.data = (void*)&wb_data;
        user_data.value1 = lchip;

        CTC_ERROR_GOTO(ctc_hash_traverse(p_xdata_master[lchip]->fk_hash, _sys_usw_xdata_wb_sync_fk_func, (void*)(&user_data)), ret, done);
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
        }

        CTC_WB_SYNC_END_DATA( CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_FLEX_KEY);
    }

done:
    SYS_XDATA_UNLOCK(lchip);
    CTC_WB_FREE_BUFFER(wb_data.buffer);

    return ret;
}

int32
sys_usw_xdata_wb_restore(uint8 lchip)
{
    int32  ret       = CTC_E_NONE;
    ctc_wb_query_t wb_query;
    sys_wb_xdata_master_t wb_xdata_master;
    sys_wb_xdata_flex_key_t wb_xdata_fk;
    sys_wb_xdata_path_t wb_xdata_path;
    sys_wb_xdata_profile_t wb_xdata_prof;
    sys_xdata_prof_info_t * p_xdata_prof = NULL;
    sys_xdata_path_info_t* p_xdata_path = NULL;
    sys_xdata_fk_db_t* p_xdata_fk = NULL;
    sys_xdata_local_t* p_xdata_local = NULL;
    sys_wb_xdata_local_t* p_wb_xdata_local = NULL;
    uint32 entry_cnt = 0;
    uint8 loop = 0;
    uint8 loop1 = 0;

    CTC_WB_ALLOC_BUFFER(&wb_query.buffer);

    /* restore xdata master */
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_xdata_master_t, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_MASTER);
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_xdata_master, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        if (CTC_WB_VERSION_CHECK(SYS_WB_VERSION_XDATA, wb_xdata_master.version))
        {
            ret = CTC_E_VERSION_MISMATCH;
            goto done;
        }
        for(loop = 0; loop < CTC_XDATA_LOCAL_TYPE_MAX; loop++)
        {
            p_xdata_local = &p_xdata_master[lchip]->local[loop];
            p_wb_xdata_local = &wb_xdata_master.local[loop];
            p_xdata_local->mode = p_wb_xdata_local->mode;
            p_xdata_local->num = p_wb_xdata_local->num;
            p_xdata_local->type = p_wb_xdata_local->type;
            p_xdata_local->ref_cnt = p_wb_xdata_local->ref_cnt;
            for(loop1 = 0; loop1 < SYS_XDATA_LOCAL_FIELD_MAX; loop1++)
            {
                sal_memcpy(&p_xdata_local->field[loop1], &p_wb_xdata_local->field[loop1],sizeof(sys_xdata_local_field_t));
            }
            if(1 != p_xdata_local->mode)
            {
                sal_memset(&p_xdata_master[lchip]->kset[p_xdata_local->type],0,sizeof(sys_xdata_kset_t));
                CTC_BMP_SET(p_xdata_master[lchip]->kset[p_xdata_local->type].w, CTC_FIELD_KEY_XDATA);
            }
        }
        entry_cnt++;
    CTC_WB_QUERY_ENTRY_END((&wb_query));

    /* restore xdata prof */
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_xdata_profile_t, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PROF);
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_xdata_prof, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        entry_cnt++;

        p_xdata_prof = mem_malloc(MEM_XDATA_MODULE, sizeof(sys_xdata_prof_info_t));
        if (NULL == p_xdata_prof)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_xdata_prof, 0, sizeof(sys_xdata_prof_info_t));

        CTC_ERROR_GOTO(_sys_usw_xdata_prof_wb_mapping(lchip, &wb_xdata_prof, p_xdata_prof, 0, 0), ret, done);

    CTC_WB_QUERY_ENTRY_END((&wb_query));


    /* restore xdata path */
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_xdata_path_t, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PATH);
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_xdata_path, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        entry_cnt++;

        p_xdata_path = mem_malloc(MEM_XDATA_MODULE, sizeof(sys_xdata_path_info_t));
        if (NULL == p_xdata_path)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_xdata_path, 0, sizeof(sys_xdata_path_info_t));

        CTC_ERROR_GOTO(_sys_usw_xdata_path_wb_mapping(lchip, &wb_xdata_path, p_xdata_path, 0, 0), ret, done);

    CTC_WB_QUERY_ENTRY_END((&wb_query));

    /* restore xdata path */
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_xdata_flex_key_t, CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_FLEX_KEY);
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_xdata_fk, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        entry_cnt++;

        p_xdata_fk = mem_malloc(MEM_XDATA_MODULE, sizeof(sys_xdata_fk_db_t));
        if (NULL == p_xdata_fk)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_xdata_fk, 0, sizeof(sys_xdata_fk_db_t));

        CTC_ERROR_GOTO(_sys_usw_xdata_fk_wb_mapping(lchip, &wb_xdata_fk, p_xdata_fk, 0), ret, done);
        if (NULL == ctc_hash_insert(p_xdata_master[lchip]->fk_hash, (void*)p_xdata_fk))
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }

    CTC_WB_QUERY_ENTRY_END((&wb_query));


done:
    CTC_WB_FREE_BUFFER(wb_query.buffer);

    return ret;

}

int32
_sys_usw_xdata_init_wb(uint8 lchip)
{
    ctc_wb_appid_t  appid;
    sal_memset(&appid,0,sizeof(appid));

    /* SYS_WB_APPID_SUBID_XDATA_MASTER */
    appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_MASTER) ;
    appid.entry_num = 1;
    appid.entry_size  = sizeof(sys_wb_xdata_master_t);
    appid.rt_en = 0;
    ctc_wb_add_appid( lchip, &appid);

    /* SYS_WB_APPID_SUBID_XDATA_PROF */
    appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PROF) ;
    appid.entry_num = SYS_XDATA_PROF_NUM;
    appid.entry_size  = sizeof(sys_wb_xdata_profile_t);
    appid.rt_en = 0;
    ctc_wb_add_appid( lchip, &appid);

    /* SYS_WB_APPID_SUBID_XDATA_PATH */
    appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_PATH) ;
    appid.entry_num = SYS_XDATA_PATH_NUM;
    appid.entry_size  = sizeof(sys_wb_xdata_path_t);
    appid.rt_en = 0;
    ctc_wb_add_appid( lchip, &appid);

    /* SYS_WB_APPID_SUBID_XDATA_FLEX_KEY */
    appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_XDATA, SYS_WB_APPID_XDATA_SUBID_FLEX_KEY) ;
    appid.entry_num = SYS_XDATA_FK_NUM;
    appid.entry_size  = sizeof(sys_wb_xdata_flex_key_t);
    appid.rt_en = 0;
    ctc_wb_add_appid( lchip, &appid);

    return CTC_E_NONE;
}


char* fk_node_str[SYS_XDATA_LOCAL_TYPE_MAX] = {
    "SCL",
    "EGS SCL",
    "Flow Hash",
    "Flow Hash Ext",
    "IPFIX",
    "EGS IPFIX",
    "Tunnel",
    "MAC",
    "IP",
    "XHASH"
};


STATIC int32
_sys_usw_xdata_show_traverse_flexkey(void* bucket_data, void* user_data)
{
    sal_file_t p_f = NULL;
    sys_xdata_fk_db_t* p_fk_db = (sys_xdata_fk_db_t*) bucket_data;
    sys_traverse_t* traversal_data = (sys_traverse_t *)user_data;
    uint8 lchip = traversal_data->value1;
    sys_xdata_fk_db_t fk_db_lkup;
    sys_xdata_fk_db_t* p_fk_node = NULL;
    ctc_listnode_t *node = NULL;
    sys_xdata_fk_f_db_t* pf_db_node = NULL;
    char    key_name[50] = {0};

    p_f = (sal_file_t)traversal_data->data;
    sal_memset(&fk_db_lkup, 0, sizeof(fk_db_lkup));
    drv_get_table_property(lchip, DRV_TABLE_PROP_GET_NAME, p_fk_db->tbl_id, 0, key_name);

    fk_db_lkup.type = p_fk_db->type;
    fk_db_lkup.hash_type = p_fk_db->hash_type;
    fk_db_lkup.tbl_id = p_fk_db->tbl_id;

    p_fk_node = ctc_hash_lookup(p_xdata_master[lchip]->fk_hash, &fk_db_lkup);
    if(p_fk_node != NULL)
    {
        SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "%s\n", fk_node_str[p_fk_node->type]);
        SYS_DUMP_DB_LOG(p_f, "%s\n", "-----------------------------------------------------------------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "%-15s%-15s%-15s%-15s%-15s%-15s%-15s%-15s%-15s\n","field","father_field","mask","width","pos_sel","start_bit","bit_width","drv_offset","field_name");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "-----------------------------------------------------------------------------------------------------------------------------------");
        CTC_LIST_LOOP(p_fk_node->field_list, pf_db_node, node)
        {
            SYS_DUMP_DB_LOG(p_f, "%-15u%-15u%-15u%-15u%-15u%-15u%-15u%-15u%-15s\n",pf_db_node->field,pf_db_node->father_field,pf_db_node->mask,pf_db_node->width,pf_db_node->pos_sel,pf_db_node->start_bit,pf_db_node->bit_width,pf_db_node->drv_offset,pf_db_node->ptr_field_name);
        }
        SYS_DUMP_DB_LOG(p_f, "type:%-2uhash_type:%-2utbl_id:%-5umode:%-2ufk_prof_id:%-2ufk_mask_id:%-2ukey_sel:%-2utype_sel:%-2uudf_bmp:%-2ukey_size:%-2uis_install:%-2uudf_en:%-2utbl_name:%s\n\n",p_fk_db->type,p_fk_db->hash_type,p_fk_db->tbl_id,p_fk_db->mode,p_fk_db->fk_prof_id,p_fk_db->fk_mask_id,p_fk_db->key_sel,p_fk_db->type_sel,p_fk_db->udf_bmp,p_fk_db->key_size,p_fk_db->is_install,p_fk_db->udf_en,key_name);
    }


    return CTC_E_NONE;
}


int32
sys_usw_xdata_dump_db(uint8 lchip, sal_file_t p_f, ctc_global_dump_db_t* p_dump_param)
{
    char prof_name[CTC_XDATA_PROF_TYPE_MAX][20] = {"POST SCL","POST L3IF","POST TUNNEL","POST FWD","POST ACL","SCL","TUNNEL","MPLS","FDB","IPUC","FLOW","ACL","EGS SCL","EGS ACL"};
    uint8 prof_total_num[CTC_XDATA_PROF_TYPE_MAX] = {1,1,1,1,1,4,4,1,2,2,2,4,4,2};
    char path_name[CTC_XDATA_PATH_TYPE_MAX][15] = {"IPE-BSR","IPE-LOCAL BSR","BSR-EPE","EPE-LOOP0","EPE-LOOP1","LOOP0-IPE","LOOP1-IPE"};
    uint8 path_total_num[CTC_XDATA_PATH_TYPE_MAX] = {8,8,8,4,4,8,8};
    char local_name[CTC_XDATA_LOCAL_TYPE_MAX][15] = {"SCL","EGS SCL","FLOW HASH","FLOW HASH EXT","IPFIX","EGS IPFIX"};
    uint8 type_loop=0;
    uint8 prof_loop=0;
    uint8 map_loop=0;
    sys_xdata_prof_info_t* p_prof_info = NULL;
    sys_xdata_path_info_t* p_path_info = NULL;
    sys_xdata_local_t* p_local_info = NULL;
    sys_traverse_t user_data;

    user_data.value1 = lchip;
    user_data.data = p_f;

    SYS_XDATA_INIT_CHECK();
    SYS_XDATA_LOCK(lchip);

    SYS_DUMP_DB_LOG(p_f, "%s\n", "# XDATA");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "{");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "Master config:");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");

    SYS_DUMP_DB_LOG(p_f, "%-36s\n","Vector type: Xdata Prof");
    SYS_DUMP_DB_LOG(p_f, "%-10s%u\n","used_cnt:", p_xdata_master[lchip]->prof_vec->used_cnt);
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-36s\n","Vector type: Xdata Path");
    SYS_DUMP_DB_LOG(p_f, "%-10s%u\n","used_cnt:", p_xdata_master[lchip]->path_vec->used_cnt);
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-36s\n","Hash type: Xdata Flex Key");
    SYS_DUMP_DB_LOG(p_f, "%-10s%u\n","used_cnt:", p_xdata_master[lchip]->fk_hash->count);
    SYS_DUMP_DB_LOG(p_f, "\n");

    if(p_dump_param->detail == 1 )
    {
        SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "%-36s\n","Vector type: Xdata Prof");
        for(type_loop=0;type_loop<CTC_XDATA_PROF_TYPE_MAX;type_loop++)
        {
            for(prof_loop=0;prof_loop<prof_total_num[type_loop];prof_loop++)
            {
                p_prof_info = ctc_vector_get(p_xdata_master[lchip]->prof_vec, SYS_XDATA_ENCODE_PROF_VECTOR_IDX(type_loop, prof_loop));
                if(p_prof_info != NULL)
                {
                    SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
                    SYS_DUMP_DB_LOG(p_f, "%-15s%-7s%-12s%-12s\n",prof_name[type_loop],"Width","Src_offset","Dst_offset");
                    SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
                    break;
                }
            }
            for(prof_loop=0;prof_loop<prof_total_num[type_loop];prof_loop++)
            {
                p_prof_info = ctc_vector_get(p_xdata_master[lchip]->prof_vec, SYS_XDATA_ENCODE_PROF_VECTOR_IDX(type_loop, prof_loop));
                if(p_prof_info != NULL)
                {
                    SYS_DUMP_DB_LOG(p_f, "%s%d%5s%d:\n", "Profile:",prof_loop,"Num:",p_prof_info->num);
                    for(map_loop=0;map_loop<p_prof_info->num;map_loop++)
                    {
                        SYS_DUMP_DB_LOG(p_f, "%18d%10d%12d\n", p_prof_info->field[map_loop].width,p_prof_info->field[map_loop].src_offset,p_prof_info->field[map_loop].dst_offset);
                    }
                }
            }
        }
        SYS_DUMP_DB_LOG(p_f, "\n");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "%-36s\n","Vector type: Xdata Path");
        for(type_loop=0;type_loop<CTC_XDATA_PATH_TYPE_MAX;type_loop++)
        {
            for(prof_loop=0;prof_loop<path_total_num[type_loop];prof_loop++)
            {
                p_path_info = ctc_vector_get(p_xdata_master[lchip]->path_vec, SYS_XDATA_ENCODE_PATH_VECTOR_IDX(type_loop, prof_loop));
                if(p_path_info != NULL)
                {
                    SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
                    SYS_DUMP_DB_LOG(p_f, "%-15s%-7s%-12s%-12s\n",path_name[type_loop],"Width","Src_offset","Dst_offset");
                    SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
                    break;
                }
            }
            for(prof_loop=0;prof_loop<path_total_num[type_loop];prof_loop++)
            {
                p_path_info = ctc_vector_get(p_xdata_master[lchip]->path_vec, SYS_XDATA_ENCODE_PATH_VECTOR_IDX(type_loop, prof_loop));
                if(p_path_info != NULL)
                {
                    SYS_DUMP_DB_LOG(p_f, "%s%d%5s%d:\n","Profile:",prof_loop,"Num:",p_path_info->num);
                    for(map_loop=0;map_loop<p_path_info->num;map_loop++)
                    {
                        SYS_DUMP_DB_LOG(p_f, "%18d%10d%12d\n", p_path_info->field[map_loop].width,p_path_info->field[map_loop].src_offset,p_path_info->field[map_loop].dst_offset);
                    }
                    /*SYS_DUMP_DB_LOG(p_f, "%s%d%5s%-4d%s%-8u%s%u\n\n","Profile:",prof_loop,"Num:",p_path_info->num,"Fixed_bmp :",p_path_info->fixed_bmp,"Valid_bmp :",p_path_info->valid_bmp);*/
                    SYS_DUMP_DB_LOG(p_f, "\n");
                }
            }
        }

        SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "%-36s\n","Xdata Local");
        for(type_loop=0;type_loop<CTC_XDATA_LOCAL_TYPE_MAX;type_loop++)
        {
            p_local_info = &(p_xdata_master[lchip]->local[type_loop]);
            if(p_local_info->mode == 2)
            {
                SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
                SYS_DUMP_DB_LOG(p_f, "%-15s%-7s%-12s%-12s\n",local_name[type_loop],"Width","Src_offset","Dst_offset");
                SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
                for(map_loop=0;map_loop<p_local_info->num;map_loop++)
                {
                    SYS_DUMP_DB_LOG(p_f, "%18d%10d%12d\n", p_local_info->field[map_loop].width,p_local_info->field[map_loop].src_offset,p_local_info->field[map_loop].dst_offset);
                }
            }
            /*
            else
            {
                SYS_DUMP_DB_LOG(p_f, "%-15s\n",local_name[type_loop]);
            }
            SYS_DUMP_DB_LOG(p_f, "%-6s%-9d%s%-8u%s%u\n", "Mode :",p_local_info->mode,"Num :",p_local_info->num,"Ref_cnt :",p_local_info->ref_cnt);
            SYS_DUMP_DB_LOG(p_f, "\n");*/
        }
        SYS_DUMP_DB_LOG(p_f, "\n");
        SYS_DUMP_DB_LOG(p_f, "%s\n", "------------------------------------------------------");
        SYS_DUMP_DB_LOG(p_f, "%-36s\n","Hash type: Xdata Flex Key");
        ctc_hash_traverse(p_xdata_master[lchip]->fk_hash,_sys_usw_xdata_show_traverse_flexkey, &user_data);

    }

    SYS_DUMP_DB_LOG(p_f, "%s\n", "}");

    SYS_XDATA_UNLOCK(lchip);
    return CTC_E_NONE;

}


int32
_sys_usw_xdata_default_init(uint8 lchip)
{
    ctc_xdata_prof_t profile;
    ctc_xdata_map_t field[SYS_XDATA_PROF_FIELD_MAX];
    ctc_xdata_local_t local;
    ctc_xdata_map_t local_field[SYS_XDATA_LOCAL_FIELD_MAX];
    ds1_t ds;
    uint32 cmd = 0;
    uint16 loop = 0;
    uint8  step = 0;

    sal_memset(&profile, 0, sizeof(ctc_xdata_prof_t));
    sal_memset(&field, 0, SYS_XDATA_PROF_FIELD_MAX*sizeof(ctc_xdata_map_t));
    sal_memset(&local, 0, sizeof(ctc_xdata_local_t));
    sal_memset(&local_field, 0, SYS_XDATA_LOCAL_FIELD_MAX*sizeof(ctc_xdata_map_t));

    profile.map = field;
    local.fields = local_field;

    for(loop = 0; loop < CTC_XDATA_LOCAL_TYPE_MAX; loop++)
    {
        local.mode = 1;
        local.type = loop;
        CTC_ERROR_RETURN(sys_usw_xdata_set_local(lchip, &local));
    }

    cmd = DRV_IOR(IpeFwdXCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));
    SetIpeFwdXCtl(V, xPHTypeSel_f, ds, SYS_XPI_PATH_TYPE_OFFSET / 4);
    SetIpeFwdXCtl(V, xPHTypeEn_f, ds, 1);
    /*gXHeader[xHeaderId(2,0)].xType*/
    step = IpeFwdXCtl_gXHeader_1_xType_f - IpeFwdXCtl_gXHeader_0_xType_f;
    loop = 0;
    do
    {
        SetIpeFwdXCtl(V, gXHeader_0_xType_f + step*loop, ds, loop);
    }    while (++loop < 8);
    cmd = DRV_IOW(IpeFwdXCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, ds));

    return CTC_E_NONE;
}


int32
sys_usw_xdata_init(uint8 lchip)
{
    int32 ret = CTC_E_NONE;
    uint8 loop = 0;
    sys_usw_opf_t opf;
    uint8  entry_num[SYS_XDATA_FK_PROF_NODE_NUM] = {8, 2, 4, 8, 4, 4, 4};
    uint8  mask_num[SYS_XDATA_FK_PROF_NODE_NUM] = {8, 2, 2, 8, 4, 4, 4};

    SYS_VCHIP_MASTER_INIT(lchip, p_xdata_master, CTC_FEATURE_CHIP);

    if (p_xdata_master[lchip])
    {
        return CTC_E_NONE;
    }
    MALLOC_ZERO(MEM_XDATA_MODULE, p_xdata_master[lchip], sizeof(sys_xdata_master_t));
    if (!p_xdata_master[lchip])
    {
        return CTC_E_NO_MEMORY;

    }

    ret = sal_mutex_create(&(p_xdata_master[lchip]->mutex));
    if (ret || !(p_xdata_master[lchip]->mutex))
    {
        ret = CTC_E_NO_RESOURCE;
        goto error0;
    }

    p_xdata_master[lchip]->fk_hash = ctc_hash_create(XDATA_FLEX_KEY_HASH_SIZE/CTC_HASH_32_BLOCK_SIZE,
                                           CTC_HASH_32_BLOCK_SIZE,
                                           (hash_key_fn) _sys_xdata_fk_hash_make,
                                           (hash_cmp_fn) _sys_xdata_fk_hash_cmp);
    if (!p_xdata_master[lchip]->fk_hash)
    {
        ret = CTC_E_NO_MEMORY;
        goto error0;
    }

    /* xdata prof vector init */
    p_xdata_master[lchip]->prof_vec = ctc_vector_init(CTC_XDATA_PROF_TYPE_MAX, CTC_CONST8);
    if (!p_xdata_master[lchip]->prof_vec)
    {
        ret = CTC_E_NO_MEMORY;
        goto error0;
    }

    p_xdata_master[lchip]->path_vec = ctc_vector_init(CTC_XDATA_PATH_TYPE_MAX, CTC_CONST8);
    if (!p_xdata_master[lchip]->path_vec)
    {
        ret = CTC_E_NO_MEMORY;
        goto error0;
    }

    CTC_ERROR_GOTO( sys_usw_opf_init(lchip, &p_xdata_master[lchip]->opf_type_fk_prof, SYS_XDATA_FK_PROF_NODE_NUM , "opf-fk-prof"),
                    ret,
                    error0);
    sal_memset(&opf,0,sizeof(sys_usw_opf_t));
    opf.pool_type  = p_xdata_master[lchip]->opf_type_fk_prof;
    opf.pool_index = SYS_XDATA_FK_PROF_NODE_I_SCL;
    do{
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, 0, entry_num[opf.pool_index]), ret, error0);
    }while(++opf.pool_index < SYS_XDATA_FK_PROF_NODE_NUM);


    /*flex key mask spool init*/
    CTC_ERROR_GOTO( sys_usw_opf_init(lchip, &p_xdata_master[lchip]->opf_type_fk_mask, SYS_XDATA_FK_PROF_NODE_NUM , "opf-fk-mask"),
                    ret,
                    error0);

    opf.pool_type  = p_xdata_master[lchip]->opf_type_fk_mask;
    opf.pool_index = SYS_XDATA_FK_PROF_NODE_I_SCL;
    do{
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, 0, mask_num[opf.pool_index]), ret, error0);
    }while(++opf.pool_index < SYS_XDATA_FK_PROF_NODE_NUM);

    CTC_ERROR_GOTO(sys_usw_xdata_local_kset_init(lchip), ret,error0);
    CTC_ERROR_GOTO(_sys_usw_xdata_fk_f_info_init(lchip), ret,error0);
    CTC_ERROR_GOTO(_sys_usw_xdata_global_init(lchip), ret,error0);

    for(loop = 0; loop < SYS_XDATA_LOCAL_TYPE_MAX; loop++)
    {
        CTC_BMP_SET(p_xdata_master[lchip]->kset[loop].w, CTC_FIELD_KEY_XDATA);
    }
    CTC_ERROR_GOTO(_sys_usw_xdata_default_init(lchip), ret,error0);
    CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_XDATA, sys_usw_xdata_dump_db), ret,error0);

    CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_XDATA,SYS_WB_APPID_XDATA_SUBID_MAX, sys_usw_xdata_wb_sync), ret, error0);

    if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_GOTO(sys_usw_xdata_wb_restore(lchip), ret, error0);
    }

    if(CTC_WB_ENABLE(lchip))
    {
        _sys_usw_xdata_init_wb(lchip);
    }

    sys_usw_mchip_set_feature_en(lchip,CTC_FEATURE_XDATA);

    return CTC_E_NONE;

    error0:
    sys_usw_xdata_deinit(lchip);
    return CTC_E_INIT_FAIL;
}

int32
sys_usw_xdata_fk_get_flex_bits(uint8 lchip, void* p_param)
{
    sys_xdata_fk_t* p_fk = (sys_xdata_fk_t*)p_param;
    sys_xdata_fk_db_t fk_node;
    uint32 ori_min_offset = 0;
    uint32 max_offset = 0;
    fields_t* p_field = NULL;
    const _sys_xdata_fk_info_t* p_fk_info = NULL;
    uint32 entry_num = 0;

    sal_memset(&fk_node,0, sizeof(sys_xdata_fk_db_t));
    fk_node.hash_type = p_fk->hash_type;
    fk_node.type = p_fk->type;
    fk_node.mode = p_fk->mode;
    fk_node.tbl_id = p_fk->tbl_id;

    p_fk_info = sys_usw_xdata_get_fk_info(lchip, &fk_node);
    if (!p_fk_info)
    {
        return CTC_E_INVALID_PARAM;
    }
    drv_get_table_property(lchip, DRV_TABLE_PROP_FIELD_INFO, p_fk_info->tbl_id,
                           p_fk_info->fld_id, &p_field);
    sys_usw_ftm_query_table_entry_num(lchip, p_fk->tbl_id, &entry_num);
    if (!p_field || !entry_num)
    {
        return CTC_E_NO_RESOURCE;
    }

    switch (p_fk->mode)
    {
        case SYS_XDATA_FK_MODE_REPLACE1 : /*append*/
            ori_min_offset = drv_get_table_max_band(lchip, p_fk->tbl_id);
            max_offset = (p_field->ptr_seg[0].word_offset << 5) + p_field->ptr_seg[0].start + p_field->ptr_seg[0].bits;
            p_fk->flex_bits = (max_offset > ori_min_offset) ? (max_offset - ori_min_offset) : 0;
            break;
        case SYS_XDATA_FK_MODE_REPLACE2 : /*replace*/
        case SYS_XDATA_FK_MODE_APPEND : /*double append*/
            p_fk->flex_bits = p_field->bits;
            break;
        default:
            return CTC_E_NOT_SUPPORT;
    }
    if ((CTC_XDATA_LOCAL_TYPE_EGS_IPFIX == p_fk->type ||
        CTC_XDATA_LOCAL_TYPE_IPFIX == p_fk->type) )
    {
        if (SYS_XDATA_FK_MODE_APPEND != p_fk->mode && p_fk->flex_bits > 129)
        {
            p_fk->flex_bits = 0;/* ipfix must support 128 flex bits */
            return CTC_E_NONE;
        }
        if (SYS_XDATA_FK_MODE_APPEND == p_fk->mode && p_fk->flex_bits && p_fk->flex_bits > 129)
        {
            p_fk->flex_bits = p_fk->flex_bits / 2;
        }
        p_fk->flex_bits = p_fk->flex_bits? (p_fk->flex_bits - 1) : 0;
    }


    return CTC_E_NONE;
}

int32
sys_usw_xdata_get_status(uint8 lchip)
{
    char prof_name[CTC_XDATA_PROF_TYPE_MAX][20] = {"POST SCL","POST L3IF","POST TUNNEL","POST FWD","POST ACL","SCL","TUNNEL","MPLS","FDB","IPUC","FLOW","ACL","EGS SCL","EGS ACL"};
    uint8 prof_total_num[CTC_XDATA_PROF_TYPE_MAX] = {1,1,1,1,1,4,4,1,2,2,2,4,4,2};
    char local_name[CTC_XDATA_LOCAL_TYPE_MAX][15] = {"SCL","EGS SCL","FLOW HASH","FLOW HASH EXT","IPFIX","EGS IPFIX"};
    char path_name[CTC_XDATA_PATH_TYPE_MAX][15] = {"IPE-BSR","IPE-LOCAL BSR","BSR-EPE","EPE-LOOP0","EPE-LOOP1","LOOP0-IPE","LOOP1-IPE"};
    uint8 path_total_num[CTC_XDATA_PATH_TYPE_MAX] = {8,8,8,4,4,8,8};
    sys_xdata_prof_info_t* p_prof_info = NULL;
    sys_xdata_path_info_t* p_path_info = NULL;
    sys_xdata_local_t* p_local_info = NULL;
    uint8 type_loop = 0;
    uint8 prof_loop = 0;
    uint8 prof_num = 0;

    SYS_XDATA_INIT_CHECK();

    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "--------------Profile Resource----------\n");
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-13s%-13s%-18s\n", "Module", "Total Num" ,"Used Num");
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------\n");
    for(type_loop=CTC_XDATA_PROF_TYPE_POST_MAX;type_loop<CTC_XDATA_PROF_TYPE_MAX;type_loop++)
    {
        prof_num = 0;
        for(prof_loop=0;prof_loop<prof_total_num[type_loop];prof_loop++)
        {
            p_prof_info = ctc_vector_get(p_xdata_master[lchip]->prof_vec, SYS_XDATA_ENCODE_PROF_VECTOR_IDX(type_loop, prof_loop));
            if(p_prof_info != NULL)
            {
                prof_num++;
            }
        }
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-17s%-13d%-18d\n", prof_name[type_loop], prof_total_num[type_loop] ,prof_num);
    }

    for(type_loop=0;type_loop<CTC_XDATA_PROF_TYPE_POST_MAX;type_loop++)
    {
        prof_num = 0;
        p_prof_info = ctc_vector_get(p_xdata_master[lchip]->prof_vec, SYS_XDATA_ENCODE_PROF_VECTOR_IDX(type_loop, 0));
        if(p_prof_info != NULL)
        {
            prof_num++;
        }
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-17s%-13d%-18d\n", prof_name[type_loop], prof_total_num[type_loop] ,prof_num);
    }

    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "--------------Local Xdata Mode----------\n");
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-16s%-16s\n", "Module", "Mode");
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------\n");
    for(type_loop=0;type_loop<CTC_XDATA_LOCAL_TYPE_MAX;type_loop++)
    {
        p_local_info = &(p_xdata_master[lchip]->local[type_loop]);
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-17s%-16d\n", local_name[type_loop],p_local_info->mode);
    }

    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "--------------Path Resource-------------\n");
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-13s%-13s%-18s\n", "Module", "Total Num" ,"Used Num");
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "----------------------------------------\n");

    for(type_loop=0;type_loop<CTC_XDATA_PATH_TYPE_MAX;type_loop++)
    {
        prof_num = 0;
        for(prof_loop=0;prof_loop<8;prof_loop++)
        {
            p_path_info = ctc_vector_get(p_xdata_master[lchip]->path_vec, SYS_XDATA_ENCODE_PATH_VECTOR_IDX(type_loop, prof_loop));
            if(p_path_info != NULL)
            {
                prof_num++;
            }
        }
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-17s%-13d%-18d\n", path_name[type_loop],path_total_num[type_loop],prof_num);
    }
    return 0;
}

#define SYS_XDATA_INFO_NODE_MAX_NUM     20
#define SYS_XDATA_INFO_MAP_MAX_NUM     20

struct sys_xdata_node_info_s
{
    char  node_name[SYS_XDATA_INFO_NODE_MAX_NUM][20];      /*xdata node name*/
    uint8 node_type[SYS_XDATA_INFO_NODE_MAX_NUM][2];       /*the first param:which type in struct,the second param:which struct 0.profile struct 1.path struct 2.post struct*/
    uint8 node_profile_num[SYS_XDATA_INFO_NODE_MAX_NUM];   /*xdata node profile num*/
    uint8 node_num;                                        /*xdata node num*/
    uint8 node_map[SYS_XDATA_INFO_MAP_MAX_NUM][3];         /*xdata map:width src-offset dst-offset*/
};
typedef struct sys_xdata_node_info_s sys_xdata_node_info_t;

int32
_sys_usw_xdata_get_info(uint8 lchip,uint8 offset_start,uint8 offset_end,uint8 type)
{
    sys_xdata_node_info_t* node_info = NULL;
    sys_xdata_path_info_t* p_path_info = NULL;
    sys_xdata_prof_info_t* p_prof_info = NULL;
    uint8 type_loop=0;
    uint8 prof_loop=0;
    uint8 map_loop=0;
    uint8 map_num = 0;
    uint8 map_btmap[32]={0};
    uint8 zero[16]={0};
    uint8 map_btmap_loop=0;
    uint8 map_bitmap_dst=0;
    uint8 map_bitmap_width= 0;

    node_info = mem_malloc(MEM_XDATA_MODULE, 6 * sizeof(sys_xdata_node_info_t));
    if (!node_info)
    {
        return CTC_E_NO_MEMORY;
    }

    node_info[0] = (sys_xdata_node_info_t) {{"LOOP0-IPE","LOOP1-IPE","SCL","POST SCL","POST L3IF","TUNNEL","MPLS","POST TUNNEL","FLOW","IPUC","FDB","POST FWD","ACL","POST ACL"},{{CTC_XDATA_PATH_TYPE_LOOP0_IPE,1},{CTC_XDATA_PATH_TYPE_LOOP1_IPE,1},{CTC_XDATA_PROF_TYPE_DSSCL,0},{CTC_XDATA_PROF_TYPE_POST_SCL,2},{CTC_XDATA_PROF_TYPE_POST_L3IF,2},{CTC_XDATA_PROF_TYPE_DSTUNNEL,0},{CTC_XDATA_PROF_TYPE_DSMPLS,0},{CTC_XDATA_PROF_TYPE_POST_TUNNEL,2},{CTC_XDATA_PROF_TYPE_DSFLOW,0},{CTC_XDATA_PROF_TYPE_DSIPDA,0},{CTC_XDATA_PROF_TYPE_DSMACDA,0},{CTC_XDATA_PROF_TYPE_POST_FWD,2},{CTC_XDATA_PROF_TYPE_DSACL,0},{CTC_XDATA_PROF_TYPE_POST_ACL,2}},{8,8,4,1,1,4,1,1,2,2,2,1,4,1},14,{{0,0,0}}};
    node_info[1] = (sys_xdata_node_info_t) {{"IPE-BSR","MET"},{{CTC_XDATA_PATH_TYPE_IPE_BSR,1},{SYS_XDATA_PROF_TYPE_DSMET,0}},{8,8},2,{{0,0,0}}};
    node_info[2] = (sys_xdata_node_info_t) {{"IPE-LBSR"},{{CTC_XDATA_PATH_TYPE_IPE_LOCAL_BSR,1}},{8},1,{{0,0,0}}};
    node_info[3] = (sys_xdata_node_info_t) {{"BSR-EPE","EGS SCL","EGS ACL"},{{CTC_XDATA_PATH_TYPE_BSR_EPE,1},{CTC_XDATA_PROF_TYPE_EGS_DSSCL,0},{CTC_XDATA_PROF_TYPE_EGS_DSACL,0}},{8,4,2},4,{{0,0,0}}};
    node_info[4] = (sys_xdata_node_info_t) {{"EPE-LOOP0"},{{CTC_XDATA_PATH_TYPE_EPE_LOOP0,1}},{4},1,{{0,0,0}}};
    node_info[5] = (sys_xdata_node_info_t) {{"EPE-LOOP1"},{{CTC_XDATA_PATH_TYPE_EPE_LOOP1,1}},{4},1,{{0,0,0}}};

    for(type_loop=0;type_loop<node_info[type].node_num;type_loop++)
    {
        for(prof_loop=0;prof_loop<node_info[type].node_profile_num[type_loop];prof_loop++)
        {
            if(node_info[type].node_type[type_loop][1]==1)
            {
                p_path_info = ctc_vector_get(p_xdata_master[lchip]->path_vec, SYS_XDATA_ENCODE_PATH_VECTOR_IDX(node_info[type].node_type[type_loop][0], prof_loop));
            }
            else
            {
                p_prof_info = ctc_vector_get(p_xdata_master[lchip]->prof_vec, SYS_XDATA_ENCODE_PROF_VECTOR_IDX(node_info[type].node_type[type_loop][0], prof_loop));
            }
            if(p_path_info ==NULL && p_prof_info == NULL)
            {
                continue;
            }
            if(p_path_info!=NULL)
            {
                map_num = p_path_info->num;
                for(map_loop=0;map_loop<p_path_info->num;map_loop++)
                {
                    node_info[type].node_map[map_loop][0]=p_path_info->field[map_loop].width;
                    node_info[type].node_map[map_loop][1]=p_path_info->field[map_loop].src_offset;
                    node_info[type].node_map[map_loop][2]=p_path_info->field[map_loop].dst_offset;
                }
            }
            if(p_prof_info != NULL)
            {
                map_num = p_prof_info->num;
                for(map_loop=0;map_loop<p_prof_info->num;map_loop++)
                {
                    node_info[type].node_map[map_loop][0]=p_prof_info->field[map_loop].width;
                    node_info[type].node_map[map_loop][1]=p_prof_info->field[map_loop].src_offset;
                    node_info[type].node_map[map_loop][2]=p_prof_info->field[map_loop].dst_offset;
                }
            }

            for(map_loop=0;map_loop<map_num;map_loop++)
            {
                if(node_info[type].node_map[map_loop][2] >= offset_start*4 && node_info[type].node_map[map_loop][2] < offset_end*4)
                {
                    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n");
                    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " %-11s Prof %1d",node_info[type].node_name[type_loop],prof_loop);
                    break;
                }
            }

            for(map_loop=0;map_loop<map_num;map_loop++)
            {
                map_bitmap_dst = node_info[type].node_map[map_loop][2]/4;
                map_bitmap_width = node_info[type].node_map[map_loop][0]/4;
                for(map_btmap_loop=map_bitmap_dst;map_btmap_loop<map_bitmap_dst+map_bitmap_width;map_btmap_loop++)
                {
                    map_btmap[map_btmap_loop]=1;
                }
            }

            if (0 == sal_memcmp(&map_btmap[offset_start], zero, 16*sizeof(uint8)))
            {
                break;
            }

            for(map_btmap_loop=offset_start;map_btmap_loop < offset_end;map_btmap_loop++)
            {
                if(map_btmap_loop == offset_start )
                {
                    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " ");
                }
                if(map_btmap[map_btmap_loop]==0)
                {
                    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "     ");
                }
                if(map_btmap[map_btmap_loop]==1)
                {
                    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-----");
                }
                map_btmap[map_btmap_loop]=0;
            }
            map_num = 0;
            p_prof_info = NULL;
            p_path_info = NULL;
        }
    }
    mem_free(node_info);
    return 0;
}


int32
sys_usw_xdata_get_info(uint8 lchip)
{
    uint8 pipe_loop = 0;
    uint8 offset=0;
    char  pipe_name[6][25] = {" [----- IPE ------]"," [----- BSR ------]"," [----- LBSR -----]"," [----- EPE ------]"," [----- LOOP0 ----]"," [----- LOOP1 ----]"};
    uint8 xdata_len[6] = {32,16,16,32,16,16};

    SYS_XDATA_INIT_CHECK();
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s\n"," ---------------------------------------------------------------------------------------------------");
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s%12s%7s%48s%33s\n","|","Module","|","XDATA Offset","|");
    SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%s\n\n"," ---------------------------------------------------------------------------------------------------");

    for(pipe_loop=0;pipe_loop<6;pipe_loop++)
    {
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-19s",pipe_name[pipe_loop]);
        for(offset=0;offset<=xdata_len[pipe_loop];offset+=4)
        {
            if(offset%16==0 && offset !=0 )
            {
                _sys_usw_xdata_get_info(lchip,((offset-16)/16)*16,(offset/16)*16,pipe_loop);
            }
            if(offset%16==0 && offset < xdata_len[pipe_loop] && offset/16 == 0)
            {
                SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-1s"," ");
            }
            if(offset%16==0 && offset < xdata_len[pipe_loop] && offset/16 != 0)
            {
                SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n%-20s"," ");
            }
            if(offset < xdata_len[pipe_loop])
            {
                 SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "[%-3d][%-3d][%-3d][%-3d]",offset*4,(offset+1)*4,(offset+2)*4,(offset+3)*4);
            }
        }
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n\n");
        
    }
    return 0;
}

int32
_sys_usw_xdata_show_solid_map_inner(uint8 lchip, uint8 type, uint8 sub_type)
{
    uint8 loop = 0;
    uint8 loop1 = 0;

    if(1 == type)
    {
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s\n", "================================================================================");
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-7s%-14s%-8s\n","Width","Src-offset","FldName");
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s\n", "--------------------------------------------------------------------------------");
        for(loop = 0; loop < SYS_XDATA_LOCAL_FIELD_MAX; loop++)
        {
            SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-7d%-14d%-36s\n",
                             local_solid_map[sub_type][loop].width,
                             local_solid_map[sub_type][loop].src_offset,
                             local_solid_map[sub_type][loop].field[0]);
            for(loop1=1;loop1<local_solid_map[sub_type][loop].field_num;loop1++)
            {
                SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-21s%-46s\n","",local_solid_map[sub_type][loop].field[loop1]);
            }
        }
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s\n", "================================================================================");
    }
    else if(2 == type)
    {
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s\n", "================================================================================");
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-7s%-14s%-46s%-10s\n","Width","Src-offset","FldName",(solid_map[sub_type][loop].udf_en)? "UDF":"");
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s\n", "--------------------------------------------------------------------------------");
        for(loop = 0; loop < SYS_XDATA_LOCAL_FIELD_MAX; loop++)
        {
            if(!solid_map[sub_type][loop].field_num)
            {
                continue;
            }
            SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-7d%-14d%-46s%-8s\n",
                             solid_map[sub_type][loop].width,
                             solid_map[sub_type][loop].src_offset,
                             solid_map[sub_type][loop].field[0],
                             solid_map[sub_type][loop].udf_en? solid_map[sub_type][loop].udf :"");
            for(loop1=1;loop1<solid_map[sub_type][loop].field_num;loop1++)
            {
                SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-21s%-46s\n","",solid_map[sub_type][loop].field[loop1]);
            }
        }
        SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s\n\n", "================================================================================");
    }

    return CTC_E_NONE;
}

int32
_sys_usw_xdata_show_solid_map(uint8 lchip, uint8 type, uint8 sub_type)
{
    uint8 loop = 0;
    char* local_node[CTC_XDATA_LOCAL_TYPE_MAX] = {"Pre-SCL","Pre-EGS-SCL","Pre-FlowHash","Pre-FlowHash-EXT","Pre-IPFIX","Pre-EGS-IPFIX"};
    char* node[CTC_XDATA_PROF_TYPE_MAX] = {"Post-SCL","Post-L3IF","Post-TUNNEL","Post-FWD","Post-ACL","DSSCL","DSTUNNEL","DSMPLS","DSMACDA","DSIPDA","DSFLOW","DSACL","EGS-DSSCL","EGS_DSACL"};
    if(!type)
    {
        for(loop=0;loop<CTC_XDATA_LOCAL_TYPE_MAX;loop++)
        {
            SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s\n", "================================================================================");
            SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-7s:%-14s\n","NODE",local_node[loop]);
            type = 1;
            _sys_usw_xdata_show_solid_map_inner(lchip, type, loop);
        }
        for(loop=0;loop<CTC_XDATA_PROF_TYPE_MAX;loop++)
        {
            SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%s\n", "================================================================================");
            SYS_XDATA_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-7s:%-14s\n","NODE",node[loop]);
            type = 2;
            _sys_usw_xdata_show_solid_map_inner(lchip, type, loop);
        }
        return CTC_E_NONE;
    }

    _sys_usw_xdata_show_solid_map_inner(lchip, type, sub_type);
    return CTC_E_NONE;
}
#define SYS_XDATA_REDEFINE_MAP_FIELD(dst_map,dst_num,src_map,src_num,is_enable)\
{\
    uint8 _loop;\
    uint8 _loop1;\
    uint8 pos = is_enable ? dst_num :0;\
    for(_loop = 0;_loop < (is_enable ? src_num :dst_num);_loop++)\
    {\
        for(_loop1 = 0;_loop1 < (is_enable ? dst_num :src_num);_loop1++)\
        {\
            if(dst_map[(is_enable ? _loop1 :_loop)].src_offset == src_map[(is_enable ? _loop :_loop1)].src_offset &&\
            dst_map[(is_enable ? _loop1 :_loop)].dst_offset == src_map[(is_enable ? _loop :_loop1)].dst_offset &&\
            dst_map[(is_enable ? _loop1 :_loop)].width == src_map[(is_enable ? _loop :_loop1)].width)\
            {\
                break;\
            }\
        }\
        if(_loop1 == (is_enable ? dst_num :src_num))\
        {\
            dst_map[pos].src_offset = is_enable ? src_map[_loop].src_offset :dst_map[_loop].src_offset;\
            dst_map[pos].dst_offset = is_enable ? src_map[_loop].dst_offset :dst_map[_loop].dst_offset;\
            dst_map[pos].width = is_enable ? src_map[_loop].width :dst_map[_loop].width;\
            pos++;\
        }\
    }\
    dst_num = pos;\
}


int32
_sys_usw_xdata_func_en(uint8 lchip, sys_xdata_func_t type, uint8 enable, void* data)
{
    ctc_xdata_path_t path;
    ctc_xdata_prof_t prof;
    ctc_xdata_map_t map[SYS_XDATA_PATH_FIELD_MAX];
    ctc_xdata_map_t temp_map[SYS_XDATA_PATH_FIELD_MAX];
    drv_ftm_info_detail_t ftm_info;
    int32 ret = CTC_E_NONE;

    sal_memset(&path, 0, sizeof(path));
    sal_memset(&prof, 0, sizeof(prof));
    sal_memset(map, 0, SYS_XDATA_PATH_FIELD_MAX*sizeof(ctc_xdata_map_t));
    sal_memset(temp_map, 0, SYS_XDATA_PATH_FIELD_MAX*sizeof(ctc_xdata_map_t));

    switch (type)
    {
        case SYS_XDATA_FUNC_LOGIC_PORT_EXT:
            {
                path.prof_id = 0;
                path.type = CTC_XDATA_PATH_TYPE_IPE_BSR;
                path.map = map;
                _sys_usw_xdata_get_path(lchip, &path);
                if (enable && CTC_FLAG_ISSET(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT))
                {
                    return CTC_E_NONE;
                }
                (enable ? CTC_SET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT) : CTC_UNSET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT));
                CTC_ERROR_RETURN(_sys_usw_xdata_set_path(lchip, &path));
                path.type = CTC_XDATA_PATH_TYPE_BSR_EPE;
                _sys_usw_xdata_get_path(lchip, &path);
                enable ? CTC_SET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT) : CTC_UNSET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT);
                CTC_ERROR_RETURN(_sys_usw_xdata_set_path(lchip, &path));
            }
            break;
        case SYS_XDATA_FUNC_NAT:
            {
                ftm_info.info_type = DRV_FTM_INFO_TYPE_MAX;
                CTC_ERROR_RETURN(drv_usw_ftm_get_info_detail(lchip, &ftm_info));

                path.prof_id = 0;
                path.type = CTC_XDATA_PATH_TYPE_IPE_BSR;
                path.map = map;
                _sys_usw_xdata_get_path(lchip, &path);
                if (ftm_info.nsh_mode)
                {
                    temp_map[0].src_offset = 16;
                    temp_map[0].dst_offset = 16;
                    temp_map[0].width = 16;
                    SYS_XDATA_REDEFINE_MAP_FIELD(map, path.num, temp_map, 1, !enable);
                }
                enable ? CTC_SET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_NAT_L4_SRC_PORT|CTC_XDATA_FIXED_FIELD_NAT_L4_DST_PORT) : 
                                          CTC_UNSET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_NAT_L4_SRC_PORT|CTC_XDATA_FIXED_FIELD_NAT_L4_DST_PORT);
                CTC_ERROR_RETURN(_sys_usw_xdata_set_path(lchip, &path));
                path.type = CTC_XDATA_PATH_TYPE_BSR_EPE;
                path.map = map;
                _sys_usw_xdata_get_path(lchip, &path);
                enable ? CTC_SET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_NAT_L4_SRC_PORT|CTC_XDATA_FIXED_FIELD_NAT_L4_DST_PORT) : 
                                          CTC_UNSET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_NAT_L4_SRC_PORT|CTC_XDATA_FIXED_FIELD_NAT_L4_DST_PORT);
                CTC_ERROR_RETURN(_sys_usw_xdata_set_path(lchip, &path));
            }
            break;
        case SYS_XDATA_FUNC_FWD_TYPE:
            {
                path.prof_id = 0;
                path.type = CTC_XDATA_PATH_TYPE_IPE_BSR;
                path.map = map;
                _sys_usw_xdata_get_path(lchip, &path);
                enable ? CTC_SET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_FWD_TYPE) : CTC_UNSET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_FWD_TYPE);
                CTC_ERROR_RETURN(_sys_usw_xdata_set_path(lchip, &path));
                path.type = CTC_XDATA_PATH_TYPE_BSR_EPE;
                path.map = map;
                _sys_usw_xdata_get_path(lchip, &path);
                enable ? CTC_SET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_FWD_TYPE) : CTC_UNSET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_FWD_TYPE);
                CTC_ERROR_RETURN(_sys_usw_xdata_set_path(lchip, &path));
            }
            break;
        case SYS_XDATA_FUNC_ECMP_HASH_H:
            {
                path.prof_id = 0;
                path.type = CTC_XDATA_PATH_TYPE_IPE_BSR;
                path.map = map;
                _sys_usw_xdata_get_path(lchip, &path);
                enable ? CTC_SET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH) : CTC_UNSET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH);
                CTC_ERROR_RETURN(_sys_usw_xdata_set_path(lchip, &path));

                path.type = CTC_XDATA_PATH_TYPE_BSR_EPE;
                _sys_usw_xdata_get_path(lchip, &path);
                enable ? CTC_SET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH) : CTC_UNSET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_ECMP_HASH_HIGH);
                SYS_XDATA_REDEFINE_MAP_FIELD(map, path.num, temp_map, 0, enable);
                CTC_ERROR_RETURN(_sys_usw_xdata_set_path(lchip, &path));
            }
            break;
        case SYS_XDATA_FUNC_IP_IOAM:
        {
            uint32 val = 0;
            uint32 cmd = 0;
            IpeFwdXCtl_m ipe_fwd_xctl;
            uint16 step = 0;
            /*Step1:set xdata path inflect*/
            /*1.1 config xdata acl use prof3*/
            map[0].src_offset = SYS_ACL_NPM_IM_FLOW_ID;
            map[0].dst_offset = 16;
            map[0].width = 16;
            map[1].src_offset = SYS_ACL_NPM_IM_FLOW_ID_HIGH;
            map[1].dst_offset = 32;
            map[1].width = 4;
            map[2].src_offset = SYS_ACL_NPM_IM_BMP;
            map[2].dst_offset = 36;
            map[2].width = 4;
            map[3].src_offset = SYS_ACL_NPM_IM_XEDITPTR;
            map[3].dst_offset = 0;
            map[3].width = 8;
            map[4].src_offset = SYS_ACL_NPM_IM_XDATA_PROF_ID;
            map[4].dst_offset = 124;
            map[4].width = 4;
            prof.prof_id = 3;
            prof.num = enable ? 5 :0;
            prof.type = CTC_XDATA_PROF_TYPE_DSACL;
            prof.map = map;
            CTC_ERROR_RETURN(_sys_usw_xdata_set_profile(lchip, &prof));
            
            /*1.2 config xdata to epe use prof 2*/
            sal_memset(&path, 0, sizeof(ctc_xdata_path_t));
            path.type = CTC_XDATA_PATH_TYPE_IPE_BSR;
            path.prof_id = 2;
            path.map = map;
            _sys_usw_xdata_get_path(lchip, &path);
            temp_map[0].src_offset = 16;
            temp_map[0].dst_offset = 16;
            temp_map[0].width = 16;
            temp_map[1].src_offset = 32;
            temp_map[1].dst_offset = 32;
            temp_map[1].width = 4;
            temp_map[2].src_offset = 36;
            temp_map[2].dst_offset = 36;
            temp_map[2].width = 4;
            temp_map[3].src_offset = 0;
            temp_map[3].dst_offset = 0;
            temp_map[3].width = 8;
            temp_map[4].src_offset = 40;
            temp_map[4].dst_offset = 40;
            temp_map[4].width = 4;
            if(enable)
            {
                path.flag |= CTC_XDATA_PATH_STACKING_EN;
            }
            SYS_XDATA_REDEFINE_MAP_FIELD(map, path.num, temp_map, 5, enable);
            CTC_ERROR_GOTO(_sys_usw_xdata_set_path(lchip, &path), ret, roll_back_0);
            
            sal_memset(&path, 0, sizeof(ctc_xdata_path_t));
            path.type = CTC_XDATA_PATH_TYPE_BSR_EPE;
            path.prof_id = 2;
            path.map = map;
            _sys_usw_xdata_get_path(lchip, &path);
            temp_map[0].src_offset = 16;
            temp_map[0].dst_offset = 0;
            temp_map[0].width = 16;
            temp_map[1].src_offset = 32;
            temp_map[1].dst_offset = 16;
            temp_map[1].width = 4;
            temp_map[2].src_offset = 36;
            temp_map[2].dst_offset = 20;
            temp_map[2].width = 4;
            temp_map[3].src_offset = 0;
            temp_map[3].dst_offset = 32;
            temp_map[3].width = 8;
            temp_map[4].src_offset = 60;
            temp_map[4].dst_offset = 124;
            temp_map[4].width = 4;
            temp_map[5].src_offset = 40;
            temp_map[5].dst_offset = 24;
            temp_map[5].width = 4;
            SYS_XDATA_REDEFINE_MAP_FIELD(map, path.num, temp_map, 6, enable);
            CTC_ERROR_GOTO(_sys_usw_xdata_set_path(lchip, &path), ret, roll_back_1);
            
            sal_memset(&path, 0, sizeof(ctc_xdata_path_t));
            path.type = CTC_XDATA_PATH_TYPE_EPE_LOOP0;
            path.prof_id = 2;
            path.map = map;
            _sys_usw_xdata_get_path(lchip, &path);
            temp_map[0].src_offset = 0;
            temp_map[0].dst_offset = 0;
            temp_map[0].width = 16;
            temp_map[1].src_offset = 16;
            temp_map[1].dst_offset = 16;
            temp_map[1].width = 4;
            temp_map[2].src_offset = 20;
            temp_map[2].dst_offset = 20;
            temp_map[2].width = 4;
            SYS_XDATA_REDEFINE_MAP_FIELD(map, path.num, temp_map, 3, enable);
            CTC_ERROR_GOTO(_sys_usw_xdata_set_path(lchip, &path), ret, roll_back_2);

            sal_memset(&path, 0, sizeof(ctc_xdata_path_t));
            path.type = CTC_XDATA_PATH_TYPE_EPE_LOOP1;
            path.prof_id = 0;
            _sys_usw_xdata_get_path(lchip, &path);
            enable ? CTC_SET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_INGRESS_EN) : CTC_UNSET_FLAG(path.fixed_bmp, CTC_XDATA_FIXED_FIELD_INGRESS_EN);
            CTC_ERROR_GOTO(_sys_usw_xdata_set_path(lchip, &path), ret, roll_back_3);
            val = enable?1:0;
            cmd = DRV_IOW(EpePktProcXCtl_t, EpePktProcXCtl_xEditPtrEn_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &val), ret, roll_back_3);

            /*xedit ptr use 32~48 bit*/
            val = enable?2:0;
            cmd = DRV_IOW(EpePktProcXCtl_t, EpePktProcXCtl_xEditPtrSel_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &val), ret, roll_back_3);

            /*policer color(d-flag) use 40~44 bit*/
            step = IpeFwdXCtl_gXHeader_1_flexStatusEn_f - IpeFwdXCtl_gXHeader_0_flexStatusEn_f;
            step = step*2;
            cmd = DRV_IOR(IpeFwdXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &ipe_fwd_xctl), ret, roll_back_3);
            SetIpeFwdXCtl(V, gXHeader_0_flexStatusEn_f + step, &ipe_fwd_xctl, enable?0x8:0);
            SetIpeFwdXCtl(V, gXHeader_0_flexStatusSel_f + step, &ipe_fwd_xctl, enable?10:0);
            cmd = DRV_IOW(IpeFwdXCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &ipe_fwd_xctl), ret, roll_back_3);
            break;
        }
        case SYS_XDATA_FUNC_NSH:
        {
            ds_t ds;
            uint32 cmd = 0;
            uint32 nsh_total_num = 0;
            sys_xdata_fk_t fk;
            drv_ftm_info_detail_t ftm_info;

            if(data)
            {
                nsh_total_num = *(uint32*)data;
            }
            sal_memset(&fk, 0, sizeof(sys_xdata_fk_t));
            ftm_info.info_type = DRV_FTM_INFO_TYPE_MAX;
            CTC_ERROR_RETURN(drv_usw_ftm_get_info_detail(lchip, &ftm_info));
            fk.type = CTC_XDATA_LOCAL_TYPE_EGS_SCL;
            fk.hash_type = 0xf;
            fk.tbl_id = CTC_IS_BIT_SET(ftm_info.nsh_mode,0) ? DsEgressScl1MetadataDvpHashKey_t : DsEgressScl0MetadataDvpHashKey_t;
            fk.mode = SYS_XDATA_FK_MODE_REPLACE2;
            fk.direct_index_en = 1;
            if(enable)
            {
                fk.info.src_pos = 48/CTC_XDATA_WIDTH_4;
                fk.info.width = 16;
                fk.info.mask = 0xffff;
                fk.info.field = SYS_FK_F_XDATA;
                fk.info.ptr_field_name = "XDATA";
                CTC_ERROR_RETURN(MCHIP_XDATA(lchip)->add_fk(lchip, &fk));

                fk.info.field = SYS_FK_F_FIELD_DONE;
                fk.info.ptr_field_name = "done";
                CTC_ERROR_RETURN(MCHIP_XDATA(lchip)->add_fk(lchip, &fk));
            }
            else
            {
                CTC_ERROR_RETURN(MCHIP_XDATA(lchip)->remove_fk(lchip, &fk));
            }

            map[0].src_offset = 32;
            map[0].dst_offset = 16;
            map[0].width = 16;
            prof.prof_id = 0;
            prof.num = enable ? 1 :0;
            prof.type = CTC_XDATA_PROF_TYPE_DSACL;
            prof.map = map;
            CTC_ERROR_RETURN(_sys_usw_xdata_set_profile(lchip, &prof));

            map[0].src_offset = 16;
            map[0].dst_offset = 16;
            map[0].width = 16;
            prof.prof_id = 0;
            prof.num = enable ? 1 :0;
            prof.type = CTC_XDATA_PROF_TYPE_DSFLOW;
            prof.map = map;
            CTC_ERROR_RETURN(_sys_usw_xdata_set_profile(lchip, &prof));

            sal_memset(&path, 0, sizeof(ctc_xdata_path_t));
            path.type = CTC_XDATA_PATH_TYPE_IPE_BSR;
            path.prof_id = 0;
            path.map = map;
            _sys_usw_xdata_get_path(lchip, &path);
            temp_map[0].src_offset = 16;
            temp_map[0].dst_offset = 16;
            temp_map[0].width = 16;
            SYS_XDATA_REDEFINE_MAP_FIELD(map, path.num, temp_map, 1, enable);
            CTC_ERROR_RETURN(_sys_usw_xdata_set_path(lchip, &path));

            sal_memset(&path, 0, sizeof(ctc_xdata_path_t));
            path.type = CTC_XDATA_PATH_TYPE_BSR_EPE;
            path.prof_id = 0;
            path.map = map;
            _sys_usw_xdata_get_path(lchip, &path);
            temp_map[0].src_offset = 16;
            temp_map[0].dst_offset = 48;
            temp_map[0].width = 16;
            SYS_XDATA_REDEFINE_MAP_FIELD(map, path.num, temp_map, 1, enable);
            CTC_ERROR_RETURN(_sys_usw_xdata_set_path(lchip, &path));

            cmd = DRV_IOR(EgressSclHashLookupCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            
            SetEgressSclHashLookupCtl(V, gXTable_1_mode_f, &ds, enable ? 2: 0);
            SetEgressSclHashLookupCtl(V, gXTable_1_xKeyType_f, &ds, enable ? 0xf: 0);
            SetEgressSclHashLookupCtl(V, egressScl1KeyIndexMax_f, &ds, nsh_total_num);
            
            cmd = DRV_IOW(EgressSclHashLookupCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        }
            break;
        default:
            break;
    }



    return CTC_E_NONE;
roll_back_3:
    path.type = CTC_XDATA_PATH_TYPE_EPE_LOOP0;
    path.prof_id = 2;
    path.num = 0;
    path.map = map;
    CTC_ERROR_DUMP(_sys_usw_xdata_set_path(lchip, &path));
roll_back_2:
    path.type = CTC_XDATA_PATH_TYPE_BSR_EPE;
    path.prof_id = 2;
    path.num = 0;
    path.map = map;
    CTC_ERROR_DUMP(_sys_usw_xdata_set_path(lchip, &path));
roll_back_1:
    path.type = CTC_XDATA_PATH_TYPE_IPE_BSR;
    path.prof_id = 2;
    path.num = 0;
    path.map = map;
    CTC_ERROR_DUMP(_sys_usw_xdata_set_path(lchip, &path));
roll_back_0:
    prof.prof_id = 3;
    prof.num = 0;
    prof.type = CTC_XDATA_PROF_TYPE_DSACL;
    prof.map = map;
    CTC_ERROR_DUMP(_sys_usw_xdata_set_profile(lchip, &prof));
    return ret;
}


#endif

#endif
